"use strict"
/*
2013-09-25 - Al C - version 1.0.10 - added projected monthly total usage; config alerts if values in config.js do not match localStorage; KB-auto code
2013-09-30 - Al C - version 1.0.11A - initial integration of the traff daemon results
2013-10-01 - Al C - version 1.0.11B - more integration of the traff daemon results
2013-10-06 - Al C - version 1.0.12 - incorporating & extending whitebeards's colours patch
2013-10-29 - Al C - version 1.0.13 - on scroll hides summaries; added FAQ; can now show/hide devices in the hourly graph
2013-11-06 - Al C - version 1.0.14B - improved hiding summaries; show/hide user entries; more graphs;css tweaks and a few fixes in yamon.sh
2013-11-06 - Al C - version 1.0.15 - moved contents of Changes & FAQ tab to external js files
*/
var yamon_version='1.0.15'
var _rs_Date,_re_Date, _cr_Date, _resetDay
var countdown,lu_timer,c2timer
var oDevicesHash, oDataHash
var devices=[],names=[],usage=[]
var colours_list=['AliceBlue','DarkOliveGreen','Indigo','MediumPurple','Purple','MidnightBlue','DarkOrange','MediumSeaGreen','Red','Aqua','DarkOrchid','MediumSlateBlue','RosyBrown','AquaMarine','DarkRed','MediumSpringGreen','RoyalBlue','DarkSalmon','MediumTurquoise','SaddleBrown','DarkSeaGreen','LawnGreen','MediumVioletRed','Salmon','DarkSlateBlue','SandyBrown','DarkSlateGray','LightBlue','SeaGreen','DarkTurquoise','Blue','DarkViolet','Sienna','BlueViolet','DeepPink','Silver','Brown','DeepSkyBlue','Navy','SkyBlue','BurlyWood','DimGray','LightGreen','SlateBlue','CadetBlue','DodgerBlue','LightPink','Olive','SlateGray','Chartreuse','FireBrick','LightSalmon','OliveDrab','Snow','Chocolate','LightSeaGreen','Orange','SpringGreen','Coral','ForestGreen','LightSkyBlue','OrangeRed','SteelBlue','CornFlowerBlue','Fuchsia','LightSlateGray','Orchid','Tan','LightSteelBlue','PaleGoldenRod','Teal','Crimson','PaleGreen','Thistle','Cyan','Gold','Lime','PaleTurquoise','Tomato','DarkBlue','GoldenRod','LimeGreen','PaleVioletRed','Turquoise','DarkCyan','Gray','Violet','DarkGoldenRod','Green','Magenta','PeachPuff','Wheat','DarkGray','GreenYellow','Maroon','Peru','DarkGreen','MediumAquaMarine','Pink','DarkKhaki','HotPink','MediumBlue','Plum','Yellow','DarkMagenta','IndianRed','MediumOrchid','PowderBlue','YellowGreen','Ivory','Beige','WhiteSmoke','Bisque','Linen','OldLace','LightCoral','Lavender','Azure','Black','PapayaWhip','LightYellow','FloralWhite','LemonChiffon','AntiqueWhite','MintCream','SeaShell','LavenderBlush','LightCyan','LightGoldenrodYellow','BlanchedAlmond','MistyRose','NavajoWhite','Khaki', 'Moccasin','LightGray','Cornsilk','Gainsboro','HoneyDew','GhostWhite','White']
var dispUnits=['b','Kb','MB','GB','TB','PB']
var hourly=[],corrections=[]
var toKB,toMB,toGB,old_last_update
var _dec=$("#NumDecimals").val()||2;
Object.getPrototypeOf(localStorage).find = function(s) {
	var r=[]
	Object.keys(localStorage).forEach(function(k){
		if (k.indexOf(s)==-1) return
		r.push({'key':k,'value':localStorage.getItem(k)});
	});
	return r.sort(function(a, b) { return (a.key < b.key?1:(a.key > b.key?-1:0)); });
}
Object.getPrototypeOf(localStorage).Clear = function(s) {
	if(confirm('Are you sure you want to clear the contents of localStorage?  This cannot be undone!')){
		Object.keys(localStorage).forEach(function(k){
			localStorage.removeItem(k)
		});
	}
}
$(document).ready(function (){
	$('#yamon_version').text('v'+yamon_version)
	$('#error-notification').remove()
	$('input[name=bandwidth]').change(function(){
		$('.is-cap')[$('#bandwidth-u').is(':checked')?'hide':'show']()
		if($('#bandwidth-l').is(':checked')){
			$('#bw_cap').select();
		}
		else{
			$('#bw_cap').addClass('disabled');
			localStorage.setItem('bw_cap','')
			$('#spUsageCap').text('Unlimited').removeClass('GBytes')
		}
	})
	$('input[name=onlyUpdate]').change(function(){
		localStorage.setItem('onlyUpdate',$('input[name=onlyUpdate]:checked').val())
		clearInterval(lu_timer)
		if($('#showLive').is(':checked') && $('#onlyUpdate-n').is(':checked')){
			liveUpdates()
			lu_timer=setInterval(liveUpdates,1000*_luEvery);
		}
	})
	$('input[name=ul-redtot]').change(function(){
		localStorage.setItem('ul-redtot',$('input[name=ul-redtot]:checked').val())
		$('.th-tot').html('Totals (' + ($('#ul-redtot-y').is(':checked')?'less':'including') + ' Unlimited)')
		$('#daily-tab,#monthly-tab').removeClass('loaded')
		var ct=$('#data-tabs .tab-name').not('.not-selected').attr('id')
		load_view(ct,true)
 	})
	$('#bw_cap').focus(function(){
		$(this).removeClass('disabled')
		$('#bandwidth-l').prop('checked','checked')
		$('#bandwidth-u').prop('checked','')
	})
	$('#bw_cap').blur(function(){
		var band_cap=$(this).val();
		if(isNaN(band_cap)||band_cap<=0){
			$(this).addClass('badvalue');
			alert('The bandwidth allowance must be a positive number!\n\nPlease try again.');
		}
		else{
			$('#spUsageCap').text(band_cap).addClass('GBytes')
			localStorage.setItem('bw_cap',band_cap)
			UsageHistoryChart()
		}
	   $('.is-cap')[$('#bandwidth-l').is(':checked')?'show':'hide']()
		$('.badvalue').change(function(){
			$(this).removeClass('badvalue')
		})
	})
	$('#top-tabs .tab-name').first().siblings('.tab-name').addClass('not-selected')
	$('#data-tabs .tab-name').first().siblings('.tab-name').addClass('not-selected')
	$('#summary-tab-section, #daily-tab-section').show();
	$('#enable-lu')[localStorage.getItem('showLive')=='true'?'hide':'show']()
	$('#enable-lu').siblings()[localStorage.getItem('showLive')=='true'?'show':'hide']()
	$('.tab-name').click(function(){
		$(this).siblings('.tab-name').addClass('not-selected');
		$(this).removeClass('not-selected');
		var tab_id= '#'+$(this).attr('id')+'-section';
		$(tab_id).show(500).siblings().hide();
		$('#collapse-summary').removeClass('collapsed')
		if(tab_id=='#daily-tab-section')DrawPie('Daily');
		if(tab_id=='#monthly-tab-section')DrawPie('Monthly');	 
		if(_unlimited_usage=='1'){
			DrawPie('Unlimited')
		}
		
	})
	$('#showHourly,#showLive,#showISP').change(function(){
		var isChecked=$(this).is(':checked');
		var tid=$(this).attr('id');
		$('.'+tid)[isChecked?'slideDown':'slideUp']('slow');
		localStorage.setItem(tid,isChecked)
		if(tid=='showISP'){
			ISP_Change()
		}
		else if(tid=='showLive'){
			$('#enable-lu')[isChecked?'hide':'show']()
			$('#enable-lu').siblings()[isChecked?'show':'hide']()
			if(isChecked && $('#live-tab').is(':visible')){
				liveUpdates()
				lu_timer=setInterval(liveUpdates,1000*_luEvery);
			}
			else if(!isChecked){
				clearInterval(lu_timer)
			} 
		}
		else if(tid=='showHourly' && isChecked){
			$('#showHourly').removeClass('hidden')
			loadHourly()
		}
		$('.ishourly')[$('#showHourly').is(':checked')?'show':'hide']()
	})
	$('#data-tabs .tab-name').click(function(){
		if($(this).hasClass('loaded')) return
		var clicked_tab=$(this).attr('id')
		load_view(clicked_tab, false)
   })
   $('#NumDecimals,#DisplayBase,#DisplayUnits').change(function(){
		localStorage.setItem('DisplayUnits', $('#DisplayUnits').val())
		localStorage.setItem('DisplayBase', $('#DisplayBase').val())
		localStorage.setItem('NumDecimals', $('#NumDecimals').val())
		var du=$("#DisplayUnits").val()
		$("#spBandwidth").html(du=="auto"?"automatically sized.":'in '+dispUnits[du]+'ytes.');
		_dec=$("#NumDecimals").val()||2;
		displayBytes('#pageContent')
 	});
	$('#dataPath,#usagefile,#devicefile,#hourFileName,#liveFileName,#hmUpdateRows').change(function(){
		var tid=$(this).attr('id'), tv=$(this).val()
		$('.'+tid).text(tv);
		localStorage.setItem(tid,tv)
		if(tid=='liveFileName'||tid=='hmUpdateRows'){
		}
		else if(tid=='devicefile'){
			load_devices()
		}
		else{
			load_data()
		}
	});
	$('#collapse-summary').click(function(){
		var wt=$('#top-tabs .tab-name').not('.not-selected').attr('id')
		if($(this).hasClass('collapsed')){
			$(this).removeClass('collapsed')
			$('#'+wt+'-section.summary-tab').slideDown('slow')
		}
		else{
			$(this).addClass('collapsed')
			$('#'+wt+'-section.summary-tab').slideUp('slow')
		}
	})
	$("#fDBtn").click(function (){
		_cr_Date=_rs_Date
		$('#daily-tab').removeClass('loaded');
		load_view('daily-tab',true);
	});
	$(".pDBtn").click(function (){
		$('#bnav button').hide()
		_cr_Date=newdate(_cr_Date,-1)
		if(_cr_Date<_rs_Date){
			_cr_Date=_rs_Date
			return
		}
		$('#daily-tab').removeClass('loaded');
		load_view('daily-tab',true);
	});
	$(".nDBtn").click(function (){
		$('#bnav button').hide()
		_cr_Date=newdate(_cr_Date,1)
		if(_cr_Date>_re_Date){
			_cr_Date=_re_Date
			return
		}
		$('#daily-tab').removeClass('loaded');
		load_view('daily-tab',true);
	});
	$("#lDBtn").click(function (){
		_cr_Date=_re_Date
		$('#daily-tab').removeClass('loaded');
		load_view('daily-tab',true);
	});
	$('.go2today').click(function(){
		_cr_Date=new Date()
		$('#daily-tab').removeClass('loaded');
		load_view('daily-tab',true);
	})
	$(".linked").change(function(e){
		var tid=$(this).attr('id'), tv=$(this).val()
		if(tid=='reset_day'&&(tv==undefined||tv==''||isNaN(tv))){
			alert("Sorry this field cannot be empty and must be a number!")
			$('#'.tid).select()
			e.stopPropagation()
			return false
		}
		$('.'+tid).html(tv+(tid=='reset_day'?'<sup>'+((tv%10==1)?'st':((tv%10==2)?'nd':'th'))+'</sup>':''))
		localStorage.setItem(tid,tv)
	});
	$(".linkedURL").change(function(){
		var tid=$(this).attr('id'), tv=$(this).val()
		$('.'+tid).prop('href',tv);
		localStorage.setItem(tid,tv)
	});
	$(".u-d").click(function(){
		$('#ShowDevices').click()
	});
	$("#ShowZeroes,#ShowDevices").change(function(){
		showHideDevices();
		localStorage.setItem('ShowZeroes',$('#ShowZeroes').is(':checked'))
		localStorage.setItem('ShowDevices',$('#ShowDevices').is(':checked'))
	});
	$('#Refresh').click(function(){
		load_data();
		$("#RefreshInterval").html($("#RefreshInterval").val());
	});
	$('#Reset').click(function(){
		$("#RefreshInterval").html($("#RefreshInterval").val());
	});
	$('#StartPause').click(function(){
		if($(this).text()=='Pause'){
			clearInterval(countdown);
			$(this).text('Start')
			$('#Reset,#Refresh').fadeOut('slow')
	   }
		else{
			countdown=setInterval(countdownFunc,1000);
			$(this).text('Pause')
			$('#Reset,#Refresh').fadeIn('slow')
	   }
	});
	$("#mb-filter").change(function(){
		$('#monthly-breakdown-tab').removeClass('loaded')
		load_view('monthly-breakdown-tab',true)
		flushChanges('#monthly-breakdown-table');
	});
	$('#add-history').click(function(){
		var lr = $('.summary-row').last().attr('id').split('-');
		var mo=(lr[2]==1?12:lr[2]-1)
		var yr=lr[1]-(mo==12?1:0)
		var hid='bill-'+yr+'-'+twod(mo)+'-'+twod(lr[3])
		localStorage.setItem(hid,'0;0')
		load_data(hid)
	})
	$('#correction-row input').change(function(){
		$('.badvalue').removeClass('badvalue')
		if($(this).hasClass('cf-desc')){}
		else if(isNaN($(this).val())){
			$(this).addClass('badvalue')
			alert('This value must be a number!')
			$(this).select()
			return false
		}
		$('#monthly-tab,#monthly-breakdown-tab').removeClass('loaded')
		var desc=$('.cf-desc').val()
		var tdu=$('.cf-u input').val(),tdd=$('.cf-d input').val()
		var cd=_cr_Date.getDate()
		var da=twod(_rs_Date.getDate())
		var mo=twod(_rs_Date.getMonth()+1)
		var yr=_rs_Date.getFullYear()
		var ds=yr+'-'+mo+'-'+da

		var dcvd=(tdd-(corrections[cd]==null?0:corrections[cd].down))*toMB
		var dcvu=(tdu-(corrections[cd]==null?0:corrections[cd].up))*toMB
		if(desc==''&&(tdu==''||tdu==0)&&(tdd==''||tdd==0)){
			delete corrections[cd]
		}
		else{
			corrections[cd]={desc:desc,down:tdd, up:tdu}
		}
		localStorage.setItem('corrections'+'-'+mo+'-'+yr, JSON.stringify(corrections))
		tdu=tdu*toMB
		tdd=tdd*toMB
		$('#correction-row .TotalBytes ').attr('value',tdu+tdd)
		$('#DailyData .is_d').each(function(){
			tdd+=Number($(this).find('.downloads').attr('value'))
			tdu+=$(this).find('.uploads').attr('value')*1
		})
		$('#dailyFooter .downloads').attr('value',tdd)
		$('#dailyFooter .uploads').attr('value',tdu)
		$('#dailyFooter .TotalBytes ').attr('value',tdu+tdd)
		var ctb=Number($('#bill-'+ds+' .TotalBytes ').attr('value'))
		var ctbd=Number($('#bill-'+ds+' .downloads ').attr('value'))
		var ctbu=$('#bill-'+ds+' .uploads ').attr('value')*1
		$('#bill-'+ds+' .TotalBytes ').attr('value', ctb+dcvd+dcvu )
		$('#bill-'+ds+' .downloads ').attr('value', ctbd+dcvd )
		$('#bill-'+ds+' .uploads ').attr('value', ctbu+dcvu )

		displayBytes('#dailyFooter,#correction-row,#bill-'+ds);
		setPercents('#DailyData tr,#correction-row', tdu+tdd)
		if($('#daily-tab').hasClass('loaded'))DrawPie('Daily');
		if($('#monthly-tab').hasClass('loaded'))DrawPie('Monthly');

	})
	setFormDefaults()

	$('.required').parents('p').each(function(){
		if($(this).attr('id')==undefined)return
		var id=$(this).attr('id').split('-')[1]
		if(localStorage.getItem(id)==undefined){
			$(this).append("<span class='mval'>[&nbsp;&#x2714;&nbsp;]</span>")
		}
		$('#'.id).addClass('mval')
		var mc=$('.mval').length-1
		$('#missing-txt').text("You are currently missing "+ mc +" required value"+(mc==1?'':'s')+".")
	})
	$('.mval').click(function(){
		var id=$(this).parents('p').attr('id').split('-')[1]
		if(id=='reset_day'&&($('#reset_day').val()==undefined||$('#reset_day').val()==''||isNaN($('#reset_day').val()))){
			alert("Sorry this field cannot be empty and must be a number!")
			$('#'.tid).select()
			return false
		}
		localStorage.setItem(id, $('#'+id).val())
		$(this).remove()
		var mc=$('.mval').length-1
		$('#missing-txt').text("You are currently missing "+ mc +" required value"+(mc==1?'':'s')+".")
		if(mc==0){
			alert("Congratulations, all required values have now been specified.  The page will now reload.")
			window.location='yamon.html'
		}
	})
	if(localStorage.getItem('reset_day')==undefined||localStorage.getItem('bw_cap')==undefined||localStorage.getItem('dataPath')==undefined||localStorage.getItem('devicefile')==undefined||localStorage.getItem('usagefile')==undefined){
		$('#SECTION_TWO,#summary-tab-section,.tabs,#p-timer').hide()
		$('.intro,#settings-tab-section,#missing-txt').slideDown('slow')
	}
	else{
		load_devices()
		setSummaryTotals();
	}
	if(_traff_daemon=='1'){
		$('.is_td').show()
	}
	$('#h_sd').click(function(){
		$(this).removeClass('partial').toggleClass('checked');
		ShowDevices($(this).hasClass('checked'))
	})
	$('#h_sd-dd').click(function(){
		$('#h_sd-ddl')[$('#h_sd-ddl').is(':visible')?'slideUp':'slideDown']('slow')
	})
	var base=$("#DisplayBase").val();
	toKB=Math.pow(base,1)
	toMB=Math.pow(base,2)
	toGB=Math.pow(base,3)
	
	$('.gr-cb').change(function(){
		DrawGraph($(this).attr('id'))
		set_bd_graphs()
	})
	$('#all-graphs').click(function(){
		$('.gr-cb').prop('checked', 'checked')
		drawGraphs()
		set_bd_graphs()
	})
	$('#no-graphs').click(function(){
		$('.gr-cb').prop('checked', false)
		drawGraphs()
		set_bd_graphs()
	})
	$('#luReset').click(function(){
		$('#liveServer').html('')
		liveUpdates()
	})  
	$('#luStop').click(function(){
		$(this).fadeOut('slow','',function(){
			$('#luStart').fadeIn('slow')
		})
		clearInterval(lu_timer);
	})  
	$('#luStart').click(function(){
		$(this).fadeOut('slow','',function(){
			$('#luStop').fadeIn('slow')
		})
		liveUpdates()
		lu_timer=setInterval(liveUpdates,1000*_luEvery);
	})
	if(_unlimited_usage==1){
		$('.ul-int').html('Unlimited Interval<br/>('+ _unlimited_start +' - '+ _unlimited_end +')')
		$('.isUL').show()
		$('.th-tot').click(function(){
			if($('#ul-redtot-y').is(':checked')){
				$('#ul-redtot-n').click()
			}
			else{
				$('#ul-redtot-y').click()
			}
		})
	}
	
})
function set_bd_graphs(){
	   var bd_graphs=[]
		$('.gr-cb').each(function(){
			bd_graphs.push([$(this).attr('id'),$(this).is(':checked')])
		})
		localStorage.setItem('bd_graphs',JSON.stringify(bd_graphs))
		$('.disabled-btn').removeClass('disabled-btn')
		$('#no-graphs')[$('.gr-cb:checked').length==0?'addClass':'removeClass']('disabled-btn')
		$('#all-graphs')[$('.gr-cb').length==$('.gr-cb:checked').length?'addClass':'removeClass']('disabled-btn')
}
function twod(v){
	return ('0'+Number(v)).slice(-2)
}
function setFormDefaults(){
	var bw_cap=localStorage.getItem('bw_cap')
	if(bw_cap==undefined){
	}
	else if(bw_cap==''){
		$('#bandwidth-u').prop('checked','checked')
		$('#spUsageCap').text('Unlimited').removeClass('GBytes')
	}
	else{
		$('#bandwidth-l').prop('checked','checked')
		$('#spUsageCap').text(bw_cap).addClass('GBytes')
		$('#bw_cap').val(bw_cap)
	}
	var config_issues='';
	if(localStorage.getItem('reset_day')==null)
 	   config_issues+=(config_issues==''?'':'\n')+'- `ISP Billing Date` has no value.  It must be set to `'+_ispBillingDay+'`'
	else if(localStorage.getItem('reset_day')!=_ispBillingDay){
	   config_issues+=(config_issues==''?'':'\n')+'- `ISP Billing Date` ('+localStorage.getItem('reset_day')+') does not match the value of `_ispBillingDay` ('+_ispBillingDay+')'
	}
	if(localStorage.getItem('dataPath')==null)
 	   config_issues+=(config_issues==''?'':'\n')+'- `Path to Data` has no value.  It must be set to `'+_wwwData+'`'
	else if(localStorage.getItem('dataPath')!=_wwwData){
	   config_issues+=(config_issues==''?'':'\n')+'- `Path to Data` ('+localStorage.getItem('dataPath')+') does not match the value of `_wwwData` ('+_wwwData+')'
	}
	if(localStorage.getItem('devicefile')==null)
 	   config_issues+=(config_issues==''?'':'\n')+'- `Users & Devices` file name has no value.  It must be set to `'+_usersFileNameWWW+'`'
	else if(localStorage.getItem('devicefile')!=_usersFileNameWWW){
	   config_issues+=(config_issues==''?'':'\n')+'- `Users & Devices` file name ('+localStorage.getItem('devicefile')+') does not match the value of `_usersFileNameWWW` ('+_usersFileNameWWW+')'
	}
	if(localStorage.getItem('usagefile')==null)
 	   config_issues+=(config_issues==''?'':'\n')+'- `Usage` file name has no value.  It must be set to `'+_usageFileName+'`'
	else if(localStorage.getItem('usagefile')!=_usageFileName){
	   config_issues+=(config_issues==''?'':'\n')+'- `Usage` file name ('+localStorage.getItem('usagefile')+') does not match the value of `_usageFileName` ('+_usageFileName+')'
	}
	var t_sh=localStorage.getItem('showHourly')=='true'?1:0
	if(t_sh!=_doHourlyData){
	   config_issues+=(config_issues==''?'':'\n')+'- Show hourly checkbox value ('+t_sh+') does not match the value of _doHourlyData` ('+_doHourlyData+')'
	}
	if(localStorage.getItem('showHourly')&&(localStorage.getItem('hourFileName')!=_hourlyFileName)){
		if(!localStorage.getItem('hourFileName')){
			localStorage.setItem('hourFileName',_hourlyFileName)
		}
		else{
			config_issues+=(config_issues==''?'':'\n')+'- Hourly usage file name ('+localStorage.getItem('hourFileName')+') does not match the value of `_hourlyFileName` ('+_hourlyFileName+')'
		}
	}
	var t_lu=localStorage.getItem('showLive')=='true'?1:0
	if(t_lu!=_doHourlyData){
	   config_issues+=(config_issues==''?'':'\n')+'- Show Live Updates checkbox value ('+t_lu+') does not match the value of `_doLiveUpdates` ('+_doLiveUpdates+')'
	}
	if(localStorage.getItem('showLive')=='true'&&(localStorage.getItem('liveFileName')!=_liveFileName)){
		if(!localStorage.getItem('_liveFileName')){
			localStorage.setItem('_liveFileName',_liveFileName)
		}
		else{
			config_issues+=(config_issues==''?'':'\n')+'- Live data file name ('+localStorage.getItem('_liveFileName')+') does not match the value of `_liveFileName` ('+_liveFileName+')'
		}
	}
	var onlyUpdate=localStorage.getItem('onlyUpdate')
	if(onlyUpdate==undefined){
	}
	else if(onlyUpdate=='1'){
		$('#onlyUpdate-y').prop('checked','checked')
	}
	else{
		$('#onlyUpdate-n').prop('checked','checked')
	}

	if(config_issues!=''){
		 alert("Uh-oh!  There are some discrepancies between your saved report settings and the values in your `config.file`!  If you are viewing these reports for the first time, don't worry the next screen will help you resolve the errors highlighted below.\n\n"+config_issues+"\n\nPlease check your inputs on the `Settings` tab and ensure they match what you have in your `config.file`!\n\nIf you've just updated your YAMon installation, Al probably left his `config.file` in the zip file (and that has clobbered your previous settings)... sorry about that!")

	}
	$('#reset_day').val(localStorage.getItem('reset_day')||_ispBillingDay)
	$('#hmUpdateRows').val(localStorage.getItem('hmUpdateRows')||15)
	_resetDay=$('#reset_day').val()
	$('.reset_day').html(_resetDay+'<sup>'+((_resetDay%10==1)?'st':((_resetDay%10==2)?'nd':'th'))+'</sup>')
	$('#DisplayUnits').val(localStorage.getItem('DisplayUnits')||'auto');
	var du=$("#DisplayUnits").val()
	$('.change-units a')[du=='auto'?'first':'last']().show()
	$('.change-units a').click(function(){
		changeUnits(this)
	})	
	$("#spBandwidth").html(du=="auto"?"automatically sized.":'in '+dispUnits[du]+'ytes.');
	$('#DisplayBase').val(localStorage.getItem('DisplayBase')||'1024');
	$('#NumDecimals').val(localStorage.getItem('NumDecimals')||'1');
	_dec=$("#NumDecimals").val();
	$('#RefreshInterval').val(localStorage.getItem('RefreshInterval')||'120');
	$('.RefreshInterval').text($('#RefreshInterval').val());
	$('#ShowZeroes,#ShowDevices,#showHourly,#showLive,#showISP').each(function(){
		$(this).prop('checked',eval(localStorage.getItem($(this).attr('id'))));
	})
	$('.u-d').addClass($('#ShowDevices').is(':checked')?'c-d':'c-u')
	$('#showHourly,#showLive,#showISP').each(function(){
		$('.'+$(this).attr('id'))[$(this).is(':checked')?'show':'hide']()
	})
	if($('#showLive').is(':checked') && $('#onlyUpdate-n').is(':checked')){
		liveUpdates()
		lu_timer=setInterval(liveUpdates,1000*_luEvery);
	}

	if ($('#showHourly').is(':checked'))$('.showHourly').removeClass('hidden')
	$('#dataPath').val(localStorage.getItem('dataPath')||_wwwData);
	$('#devicefile').val(localStorage.getItem('devicefile')||_usersFileNameWWW);
	$('#usagefile').val(localStorage.getItem('usagefile')||_usageFileName);
	$('#hourFileName').val(localStorage.getItem('hourFileName')||_hourlyFileName);
	$('#liveFileName').val(localStorage.getItem('liveFileName')||'live_data.html');
	$('#isp-name').val(localStorage.getItem('isp-name')||'ISP');
	$('.isp-name').text($('#isp-name').val());
	$('#isp-url').val(localStorage.getItem('isp-url'));
	$('input[name=]').val(localStorage.getItem('ul-redtot')||1);
	var ul_redtot=localStorage.getItem('ul-redtot')
	if((ul_redtot==undefined)||(ul_redtot=='1')){
		$('#ul-redtot-y').prop('checked','checked')
	}
	else{
		$('#ul-redtot-n').prop('checked','checked')
	}
	$('.th-tot').html('Totals (' + ($('#ul-redtot-y').is(':checked')?'less':'including') + ' Unlimited)')

	$('.isp-url').prop('href',$('#isp-url').val());

	var base=$("#DisplayBase").val();
	toMB=Math.pow(base,2)
	toGB=Math.pow(base,3)

}
function setSummaryTotals(){
	flushChanges();
	var report=localStorage.find('bill')
	Object.keys(report).forEach(function(k){
		var bill=report[k].key
		var de = bill.split('-')
		var yr=de[1]
		var mo=de[2]
		var da=de[3]
		var values = report[k].value.split(';')
		var up=Number(values[0])
		var down=Number(values[1])
		var nr=$('<tr/>').attr('id',bill).addClass('summary-row')
		nr.append($('<td/>').html("<span class='interval'>"+yr+'-'+mo+'-'+da+"</span>").addClass('br'))
		nr.append($('<td/>').addClass('downloads num').attr('value',down))
		nr.append($('<td/>').addClass('uploads num  br').attr('value',up))
		nr.append($('<td/>').addClass('TotalBytes str num').attr('value',up+down))
		nr.append($('<td/>').addClass('is-cap cap GBytes').html($('#bw_cap').val()))
		nr.append($('<td/>').addClass('percent is-cap br2'))
		nr.append($('<td/>').addClass('a-c').html("<span class='rmls' title='Delete this interval' onclick=delLS('"+bill+"')>&#10008;</span>"))
		$('#SystemTotalsTable').append(nr)

	})
	$('.is-cap')[$('#bandwidth-u').is(':checked')?'hide':'show']()
	if(!$('#bandwidth-u').is(':checked')){
		setPercents('.summary-row', $('#bw_cap').val()*toGB)
	}
	UsageHistoryChart()
   $('.interval').click(function(){
		var lr=$(this).parents('tr').attr('id')
		var fr=$('#SystemTotalsTable .summary-row').first().attr('id')
		$('#DailyData,#MonthlyData,#MonthlyBreakdown, #breakdownFooter').html('')
		if(lr==fr){
			load_data()
		}
		else{
			var hid=lr.split('-')
			hid[0]='history'
			load_data(hid.join('-'))
		}
		$('.currentSummary').removeClass('currentSummary')
		$(this).parent().addClass('currentSummary')
	})
	displayBytes('#SystemTotalsTable');
}

var hashCode=function(s){
	return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}

function load_devices(){
	$('.loading').text('Loading devices...').show();
	$('.loaded').removeClass('loaded');
	var device_file=$('#dataPath').val()+$('#devicefile').val()
	$.get(device_file)
	.done(function(list,textStatus){
		var nDevicesHash=hashCode(list);
		if(oDevicesHash!=nDevicesHash){
			devices=[]
			var ul=list.split('\n'),n=1
			$.each(ul, function(){
				if(this=='') return;
				var row=this.split(',')
				var mac=row[0].toUpperCase()
				var uid=hashCode(mac)
				devices[mac]={un:n,id:uid,ip:row[1],name:row[2],device:row[3],down:0,up:0,colour:row[4],ul_down:0,ul_up:0}
				if(row[4]!=null){
					var index = (colours_list.join(",").toLowerCase().split(",")).indexOf((row[4]).toLowerCase());
					if(index!=-1){
					   colours_list.splice(index, 1);
					}
				}
				names[row[2]]={down:0,up:0}
				n++
			});
			devices
			if(_traff_daemon=='1'){
				devices['FF:FF:FF:FF:FF:FF']={un:n,id:'000000',ip:'1.1.1.1',name:'Router',device:'traff daemon',down:0, up:0,ul_down:0,ul_up:0}
				devices['PROC:NET:DEV']={un:n,id:'000001',ip:'1.1.1.2',name:'Router',device:'proc/net/dev',down:0, up:0,ul_down:0,ul_up:0}
			}
			oDevicesHash=nDevicesHash
			var sel=$("#mb-filter").val()
			$("#mb-filter").html('<option value="dd-ALL">ALL Traffic By Day</option>');
			Object.keys(devices).sort(byName).forEach(function(d){
				var id=devices[d].id
				if(id=='000000')return
				var un=devices[d].name
				var u_n=clean(un)
				var ud=devices[d].device
				var u_d=clean(ud)
				$("#mb-filter").append($("<option/>").attr('id','mbd-'+id).attr('value','dd-'+u_n+'-'+u_d).text(ud).addClass('ddl-d du-'+u_n));
			})
			var nv=0
			Object.keys(names).forEach(function(n){
				names[n].n=nv
				var nn=clean(n)
				$(".du-"+nn).first().before($("<option/>").attr('id','mbd-'+nn).attr('value','dd-'+nn).text(n).addClass('ddl-u du-'+nn));
				nv++
			})
			var show_devices=$('#ShowDevices').is(':checked')
			$('.ddl-device')[show_devices?'removeClass':'addClass']('hidden');
			$("#mb-filter").val(sel)
	}
		else{
		}
		clearInterval(countdown)
		countdown=setInterval(countdownFunc,1000)
		load_data()
	})
	.fail(function(jqxhr,settings,exception){
		alert("Could not load the devices file.\n\nPlease check your parameters on the Settings tab.\n\nAlso, check the file to ensure that the first line is not blank... for some oddball reason that is causing the loading process to fail?!?");
		$('#settings-tab').click()
	})
	$('.loading').fadeOut(1500)
}
function zeroDevicesTotal(){
	Object.keys(devices).forEach(function(k){
		devices[k].up=0
		devices[k].down=0
		devices[k].ul_up=0
		devices[k].ul_down=0
	})
	Object.keys(names).forEach(function(k){
		names[k].up=0
		names[k].down=0
		names[k].ul_up=0
		names[k].ul_down=0
	})
}
function load_data(ri){
   var da,mo,yr
   if(Object.keys(names).length==0){
		alert('Uh-oh!!  No names/devices were read from the devices file?!?\n\nPlease check the `devices` field on the Settings tab to ensure that it is pointing to the correct filename')
		return false
	}
	$('.loading').text('Loading data file...').show();
	$('.loaded').removeClass('loaded');
	var loading_history=false
	if(typeof(ri)!='undefined'){
		loading_history=true
	}
	_resetDay=$('#reset_day').val()
	var rd=twod(_resetDay)
	if(loading_history){
		var de=ri.split('-')
		da=twod(de[3])
		mo=twod(de[2])
		yr=de[1]
		clearInterval(countdown);
		$('#p-timer').fadeOut('slow')
		_rs_Date= new Date(yr,mo-1,da);
		var rm=twod(_rs_Date.getMonth()-(-1))
		_re_Date=new Date(yr,mo,da-1);
		_cr_Date=_rs_Date
	}
	else{
		_cr_Date=new Date();
		da=_cr_Date.getDate()
		var da2=twod(da)
		mo=twod(_cr_Date.getMonth()-(-1))
		yr=_cr_Date.getFullYear()
		clearInterval(countdown);
		countdown=setInterval(countdownFunc,1000);
		$('#p-timer').fadeIn('slow')
		_rs_Date=new Date(yr,mo-(da>=_resetDay?1:2),_resetDay);
		var rm=twod(_rs_Date.getMonth()-(-1))
		_re_Date=new Date(yr,mo-(da>=_resetDay?0:1),_resetDay-1, 23, 59, 59);
		$('.interval').first().parent().addClass('currentSummary')
		var bps=$('.summary-row').first().find('.TotalBytes').attr('value')/((_cr_Date-_rs_Date))
		var etb=bps*((_re_Date-_rs_Date))
		$('.summary-row').first().find('td').last().attr('value',etb).addClass('num').attr('id','estimatedMonthlyTotal').attr('title','Projected monthly total ')
		if($('#estimatedMonthlyTotal').attr('value')>Number($('#spUsageCap').text())*toGB){
			$('#estimatedMonthlyTotal').addClass('over-cap')
		}
	}
	$('.go2today')[loading_history?'fadeIn':'fadeOut']('slow')
	$('.today').text(_rs_Date.toDateString());
	corrections=JSON.parse(localStorage.getItem('corrections'+'-'+rm+'-'+yr))
	if(corrections==null){
		corrections=new Object()
	}
	var datafile=$('#dataPath').val()+rd+'-'+rm+'-'+yr+'-'+$('#usagefile').val()

	$('.current-interval').text(_rs_Date.toDateString() + ' - ' + _re_Date.toDateString());
	$.get(datafile)
	.done(function(dlist,textStatus){
		var nDataHash=hashCode(dlist);
		flushChanges();
		if(oDataHash!=nDataHash){
			var dl=dlist.split('\n'),tup=0,tdown=0
			usage=[]

			zeroDevicesTotal()
			$.each(dl, function(){
				if(this=='') return false;
				var dr=this.split(',')
				var mac=dr[0].toUpperCase()
				var ddown=Number(dr[2]),dup=Number(dr[3]),ul_down=Number(dr[5])||0,ul_up=Number(dr[6])||0
				if(mac=='FF:FF:FF:FF:FF:FF'){
					ddown=ddown*toMB
					dup=dup*toMB
				}
				if(devices[mac]===undefined){
					devices[mac]={id:'unknown',ip:dr[1],name:'Unknown',device:'Unknown',down:0, up:0,ul_down:0, ul_up:0}
				}
				usage.push({mac:mac,name:devices[mac].name,down:ddown,up:dup,date:twod(dr[4]),ul_down:ul_down, ul_up:ul_up})
				var name=devices[mac].name
				devices[mac].down+=ddown
				devices[mac].up+=dup
				devices[mac].ul_down+=ul_down
				devices[mac].ul_up+=ul_up
				if(mac=='FF:FF:FF:FF:FF:FF'||mac=='PROC:NET:DEV'){
				}
				else{
					names[name].down+=ddown
					names[name].up+=dup
					names[name].ul_down+=ul_down
					names[name].ul_up+=ul_up
					tdown+=ddown
					tup+=dup
				}
			});
			oDataHash=nDataHash

			for(var d in corrections){
				if(corrections[d]){
					tup+=corrections[d].up*toMB
					tdown+=corrections[d].down*toMB
			   }
			}

			var bill='bill-'+yr+'-'+rm+'-'+rd
			localStorage.setItem(bill,tup+';'+tdown);

			if($('#'+bill).length==0){
				var nr=$('<tr/>').attr('id',bill).addClass('summary-row')
				nr.append($('<td/>').text(yr+'-'+rm+'-'+rd).addClass('interval br'))
				nr.append($('<td/>').addClass('downloads num').attr('value',tdown))
				nr.append($('<td/>').addClass('uploads num br').attr('value',tup))
				nr.append($('<td/>').addClass('TotalBytes num').attr('value',tup+tdown))
				nr.append($('<td/>').addClass('percent is-cap'))
				nr.append($('<td/>').html("<span class='rmls' title='Delete this interval' onclick=delLS('"+bill+"')>[ - ]</span>"))
				$('#SystemTotalsTable').append(nr)
			}
			else{
				var arr=[[' .downloads',tdown], [' .uploads',tup], [' .TotalBytes',tup+tdown]]
				updateRow(bill,arr)
			}
			if($('#bandwidth-l').is(':checked')){
				setPercents('#'+bill, $('#bw_cap').val()*toGB)
			}
			displayBytes('#'+bill);
			var current_view=$('#data-tabs .tab-name').not('.not-selected').attr('id');
			load_view(current_view, loading_history);
		}
		else{
		}
	})
	.fail(function(jqxhr,settings,exception){
		alert("Could not load the data file for the date interval... the file (likely) does not exist .\n\nThe history entry will be removed from the list.");
	})
	.always(function(dlist,textStatus) {
		if(dlist==''){
			alert('Uh-oh!!  No data was read from the usage file?!?\n\nPlease ensure that the following file actually exists: \n   `'+datafile+'`')
			return false
		}
	   UsageHistoryChart()
		$('.loading').fadeOut(1500);
	})
}
function loadHourly(cleardata){
	//hourly=[]
	if(!$("#showHourly").is(':checked')) return false;
	if(cleardata){
		Object.keys(hourly).forEach(function(k){
			for(var x=0;x<24;x++){
				hourly[k].usage[x]=null
			}
		})
	}
	var da=twod(_cr_Date.getDate())
	var mo=twod(_cr_Date.getMonth()-(-1))
	var yr=_cr_Date.getFullYear()
	var datafile=$('#dataPath').val()+da+'-'+mo+'-'+yr+'-'+$('#hourFileName').val()
	$.get(datafile)
	.done(function(dlist,textStatus){
		if(dlist.length==0){
			$('#hourlyGraph').html('<h2 style="margin-left:300px;">No hourly data available!</h2>')
			var tmp=$( "h2:contains('No hourly data')" ).offset()
			$('#bnav').offset({top:tmp.top+2,left:tmp.left-40})
		   $('#bnav button').fadeIn('slow')
			return false
		}
		var dl=dlist.split('\n')
		$.each(dl, function(){
			if(this=='') return false;
			var dr=this.split(',')
			var mac=dr[0].toUpperCase()
			var hdown=Number(dr[2]),hup=Number(dr[3])
			var hr=Number(dr[4])
			if(hourly[mac]===undefined){
				hourly[mac]={name:'',usage:[],ishidden:!$('#h_sd').hasClass('checked')}
				for(var x=0;x<24;x++){
					hourly[mac].usage[x]=null
				}
			}
			hourly[mac].name=devices[mac].name
			hourly[mac].device=devices[mac].device
			hourly[mac].usage[hr]=hdown+hup
		});
		SetDevices()
		var tmp=$( "text:contains('Hour of the Day')" ).offset()
		$('#bnav').offset({top:tmp.top,left:tmp.left-40})
		$('#bnav button').fadeIn('slow')
	})
	.fail(function(jqxhr,settings,exception){
		alert('Sorry - there was an error attempting to read the hourly data file: ' + datafile)
	})
	.always(function(dlist,textStatus) {

	})
}
function SetDevices(){
	$('.legend-colour').each(function(){
		var dmac=$(this).parent('td').attr('title').split('|')[0].trim()
		var ishidden=hourly[dmac]?hourly[dmac].ishidden:false
		$(this)[ishidden?'addClass':'removeClass']('op10')
		$(this).next()[ishidden?'addClass':'removeClass']('so')
	})
	DrawHourlyGraph()
}
function ShowDevices(sh){
	$('.legend-colour').each(function(){
		var ishidden=(sh==1)
		var dmac=$(this).parent('td').attr('title').split('|')[0].trim()
		hourly[dmac].ishidden=!ishidden
		$(this)[ishidden?'removeClass':'addClass']('op10')
		$(this).next()[ishidden?'removeClass':'addClass']('so')
	})
	DrawHourlyGraph()
}
function ShowUserDevices(un){
	$('.legend-colour').each(function(){
		var ishidden=($(this).parents('tr').attr('owner-name')==un)
		var dmac=$(this).parent('td').attr('title').split('|')[0].trim()
		hourly[dmac].ishidden=!ishidden
		$(this)[ishidden?'removeClass':'addClass']('op10')
		$(this).next()[ishidden?'removeClass':'addClass']('so')
	})
	DrawHourlyGraph()
}
function DrawHourlyGraph(){
	var devicecolours=[]
	var inKbytes=true
	$('.legend-colour').not('.op10').each(function(){
		var thisbytes=$(this).parents('tr').find('.TotalBytes').hasClass('Kbytes')||$(this).parents('tr').find('.TotalBytes').hasClass('bytes')
		inKbytes=inKbytes&&thisbytes
	})
	var hdata=new google.visualization.DataTable();
	hdata.addColumn('string','Name');
	Object.keys(hourly).sort(byName).forEach(function(k){
		if(hourly[k].ishidden) return
		if(hourly[k].usage.join().replace(/[0,]/g, "")=='')return;
		hdata.addColumn('number', hourly[k].name+'-'+hourly[k].device)
		var tcolour=devices[k].colour==null?colours_list[devices[k].un]:devices[k].colour
		devicecolours.push(tcolour);
	})
	for(var x=0;x<24;x++){
		var vv=[twod(x)]
		Object.keys(hourly).sort(byName).forEach(function(k){
			if(hourly[k].ishidden) return
			if(hourly[k].usage.join().replace(/[0,]/g, "")=='')return;
			vv.push(hourly[k].usage[x]?Number((hourly[k].usage[x]/(inKbytes?toKB:toMB)).toFixed(2)):null)
		 })
		hdata.addRow(vv);
	}
	var baroptions={width:900,height:400,title:'Hourly Totals',legend:{position:'right',textStyle:{fontSize:11}},chartArea:{},isStacked:true,is3D:true,hAxis:{title:'Hour of the Day - '+$('#current-date').text(),slantedText:false,titleTextStyle:{color:'green'},textStyle:{fontSize:11}},vAxis:{title:'Total Usage in '+(inKbytes?'kB':'MB'),titleTextStyle:{color:'green'}}};
	baroptions.colors=devicecolours /* !@#$ */
	var hourlychart=new google.visualization.ColumnChart(document.getElementById('hourlyGraph'));
	hourlychart.draw(hdata,baroptions);
	
	var c_hd=$('.op10').length
	if(c_hd==0){
		$('#h_sd').removeClass('partial').addClass('checked');
		$('.fd-sel').removeClass('fd-sel')
		$('#h_fd-all').addClass('fd-sel')
		$('#h_sd-dd').text('All')
	}
	else if(c_hd==$('.legend-colour').length){
		$('#h_sd').removeClass('partial checked');
		$('.fd-sel').removeClass('fd-sel')
		$('#h_fd-none').addClass('fd-sel')
		$('#h_sd-dd').text('None')
	}
	else{
		$('#h_sd').removeClass('checked').addClass('partial');
		$('.h_fd').each(function(){
			var un=$(this).text()
			var ni = $('.is_d[owner-name='+un+']').length, nd=$('.is_d[owner-name='+un+'] .op10').length
			if(ni==0) return;
			if(nd==0){
				$(this).removeClass('fd-some').addClass('fd-sel')
			}
			else if(nd==ni){
				$(this).removeClass('fd-sel fd-some')
			}
			else{
				$(this).removeClass('fd-sel').addClass('fd-some')
			}
		})
		$('#h_sd-dd').text('Selected')

 	}
}
function countdownFunc(){
	$(".RefreshInterval").text(Number($(".RefreshInterval").html())-1);
	if ($(".RefreshInterval").text()==0){
		load_devices();
		$(".RefreshInterval").html($("#RefreshInterval").val());
	}
}
function liveUpdates(){
	var speed=1000, easing='swing'
	$.getScript(_liveFileName)
	.done(function( script, textStatus ) {
		var tt=last_update.split(' ')[1]
		var tt_id=tt.replace(/:/gi,'-')
		if(old_last_update==last_update){
			return
		}
		if($('#'+tt_id).length==0){
			var tr=$('<p/>').attr('id',tt_id).addClass('p-tr hidden')
			tr.append($('<span/>').addClass('td-time br a-r').text(tt))
			tr.append($('<span/>').addClass('td-num ls-m1').text(load1.toFixed(2)))
			tr.append($('<span/>').addClass('td-num ls-m5').text(load5.toFixed(2)))
			tr.append($('<span/>').addClass('td-num ls-m15').text(load15.toFixed(2)))
			$('#liveServer').prepend(tr)
			$('#luReset').fadeIn('slow')
			
			serverloadgraph()
			if($("#freeMem").text()==''){
				$("#freeMem").text(freeMem)
			}
			if($("#freeMem").text()==''){$("#freeMem").text(freeMem)}
			var dfm=freeMem-Number($("#freeMem").text())
			if(dfm!=0){
				c2timer=setInterval(function() { countTo(freeMem, dfm>0?1:-1)},1000*_luEvery/Math.abs(dfm*1.333));
			}
			$('#liveServer p').first().animate({opacity: 'toggle', height: 'toggle'}, speed, easing)
			while($('#liveServer p:visible').length>Number($('#hmUpdateRows').val())+1){
				$('#liveServer p:visible').last().hide()
			}
			if($('#liveServer p:visible').length>Number($('#hmUpdateRows').val())){
				$('#liveServer p:visible').last().animate({opacity: 'toggle', height: 'toggle'}, speed, easing)
			}
		}
		var dt=_luEvery
		if(old_last_update){
			dt = (Date.parse(last_update)-Date.parse(old_last_update))/1000
		}
		$('#act-cons-body').html('')
		$('#acrc').text(curr_connections.length + " Active Connection" + (curr_connections.length==1?"":'s') )
		for(var i in curr_connections){
			var nr=$('<tr/>').addClass('acon-row')
			nr.append($('<td/>').html(curr_connections[i][0]).addClass('br'))
			nr.append($('<td/>').html(curr_connections[i][1]).addClass('a-c'))
			nr.append($('<td/>').html(curr_connections[i][2]).addClass('a-c br'))
			nr.append($('<td/>').html(curr_connections[i][3]).addClass('a-c'))
			nr.append($('<td/>').html(curr_connections[i][4]).addClass('a-c br'))
			$('#act-cons-body').append(nr)
		}
		$('#curc').text(curr_users.length + " Current Device" + (curr_users.length==1?"":'s')+' (Usage in bytes)')
		for(var i in curr_users){
			var tr=$('<p/>').addClass('p-cu hidden')
			tr.append($('<span/>').addClass('td-time br a-r').text(tt))
			tr.append($('<span/>').addClass('cu-d').text(devices[curr_users[i][0]].device))
			tr.append($('<span/>').addClass('cu-o br').text(devices[curr_users[i][0]].name))
			tr.append($('<span/>').addClass('td-num').text(curr_users[i][1]))
			tr.append($('<span/>').addClass('td-num br').text((curr_users[i][1]/dt/toKB).toFixed(_dec)))
			tr.append($('<span/>').addClass('td-num').text(curr_users[i][2]))
			tr.append($('<span/>').addClass('td-num br').text((curr_users[i][2]/dt/toKB).toFixed(_dec)))
			$('#curr-users').prepend(tr)
		}
		$('#curr-users p:hidden').animate({opacity: 'toggle', height: 'toggle'}, speed, easing)
		while($('#curr-users p:visible').length>Number($('#hmUpdateRows').val())*2+1){
			$('#curr-users p:visible').last().hide()
		}
		if($('#curr-users p:visible').length>Number($('#hmUpdateRows').val())*2){
			$('#curr-users p:visible').last().animate({opacity: 'toggle', height: 'toggle'}, speed, easing)
		}
		old_last_update=last_update
	})
	.fail(function( jqxhr, settings, exception ) {
		console.log( "Triggered ajaxError handler." )
	});
}
function countTo(t,d){
	var nv=Number($("#freeMem").html())+d
	$("#freeMem").text(nv);
	if(nv>=t){
		clearInterval(c2timer)
	}
}

function serverloadgraph(){

	//if($('.p-tr').length==1) return;
	var s_usage=[]
	if($('#bandwidth-l').is(':checked')){
		 var cap=Number($('#bw_cap').val())
	}
	$('.p-tr').each(function(){
		var t=$(this).text()
		var m1=Number($(this).find('.ls-m1').text())
		var m5=Number($(this).find('.ls-m5').text())
		var m15=Number($(this).find('.ls-m15').text())
		s_usage.push([t,m1,m5,m15]);
	})
	var data;
	data=new google.visualization.DataTable();
	data.addColumn('string','Time');
	data.addColumn('number','1-min');
	data.addColumn('number','5-min');
	data.addColumn('number','15-min');
	data.addRows(s_usage.reverse());
	var baroptions={
		width:700,height:300,title:'Average Server Load',curveType:'function',fontSize:9,legend:{position:'top',fontSize:14},isStacked:true,hAxis:{title:'Time',fontSize:14,slantedText:true,titleTextStyle:{color:'green'}},vAxis:{title:'Load',fontSize:14,titleTextStyle:{color:'green'},viewWindow:{min:0}},series:{0:{lineWidth:1,color:'blue',visibleInLegend:true},1:{lineWidth:1,color:'green',visibleInLegend:true},2:{lineWidth:1,color:'red',visibleInLegend:true}}
	};
	var UsageChart=new google.visualization.LineChart(document.getElementById('sl-graph'));
	UsageChart.draw(data,baroptions);
}
function load_view(wv,cleardata){
	if(wv!='live-tab' && $('#onlyUpdate-y').is(':checked')){
		clearInterval(lu_timer);
	}
	if(! $('#'+wv).hasClass('loaded')){
		$('.loading').text('Loading view...').show();
		$('#'+wv).addClass('loaded');

		switch(wv){
			case 'daily-tab':
				if(cleardata){
					$('#DailyData,#dailyFooter').html('')
				}
				setDailyTab()
				if($('#showHourly').is(':checked')){
					loadHourly(cleardata)
				}
				break;
			case 'live-tab':
				$('#'+wv).removeClass('loaded')
				if(localStorage.getItem('showLive')=='true'){
					liveUpdates()
					clearInterval(lu_timer);
					lu_timer=setInterval(liveUpdates,1000*_luEvery);
				}

				break;
			case 'monthly-tab':
				if(cleardata){
					$('#MonthlyData,#monthlyFooter').html('')
				}
				setMonthlyTab()
				break;
			case 'monthly-breakdown-tab':
				if(cleardata){
					$('#MonthlyBreakdown,#breakdownFooter').html('')
				}
				if(localStorage["bd_graphs"]==null){
					set_bd_graphs()
				}
				var bd_graphs=JSON.parse(localStorage["bd_graphs"])
				for (var k in bd_graphs){
					$('#'+bd_graphs[k][0]).prop('checked',bd_graphs[k][1])
				} 
				$('#no-graphs')[$('.gr-cb:checked').length==0?'addClass':'removeClass']('disabled-btn')
				$('#all-graphs')[$('.gr-cb').length==$('.gr-cb:checked').length?'addClass':'removeClass']('disabled-btn')
				monthlyBreakdown()
				break;
			case 'devices-tab':
				setDevicesTab()
				break;
		}
	}
	changelegend()

	if($('#'+wv).hasClass('not-selected')) {
		$('#'+wv).siblings().addClass('not-selected');
		$('#'+wv).removeClass('not-selected');
		var tab_id= '#'+wv+'-section';
		$(tab_id).siblings().hide();
		$(tab_id).show();
	};
	showHideDevices()
	$('.loading').fadeOut(1500);
}

function setDailyTab(){
	var tag=$("#DailyData");
	var today=new Date();
	_cr_Date=_cr_Date||today
	$('.current-date').text(_cr_Date.toDateString());
	$('.go2today')[$('.interval').first().parent().hasClass('currentSummary')?(_cr_Date==today?'fadeOut':'fadeIn'):'fadeOut']('slow');
	$('#tdaemon, #tdaemon-diff,#tpnd, #tpnd-diff').remove()
	var cd=_cr_Date.getDate()
	var mo=_rs_Date.getMonth()+1
	var yr=_rs_Date.getFullYear()
	if(corrections==null||corrections[cd]==null){
		$('#correction-row,#remove-correction').hide()
		var cdu=0,cdd=0,cddesc=''
		var has_corr=0
		$('#add-correction').slideDown('slow')
	}
	else{
		$('#correction-row,#remove-correction').show()
		$('#add-correction').hide()
		var cddesc=corrections[cd].desc,cdu=corrections[cd].up,cdd=corrections[cd].down
		var has_corr=1
	}
	$('.cf-desc').val(cddesc)
	$('.cf-u input').val(cdu)
	$('.cf-d input').val(cdd)
	var current_day=twod(_cr_Date.getDate())
	var dnames=[]
	var dataset=getUsage('date',current_day)
	var nrd=dataset.length+has_corr

	var utot=cdu*toMB,dtot=cdd*toMB,ul_utot=0,ul_dtot=0
	var total=utot+dtot
	$('#correction-row .TotalBytes').attr('value',utot+dtot)
	var tdaemon='', tdaemon_diff='', tpnd='', tpnd_diff=''
	var ul_redtot=$('#ul-redtot-y').is(':checked')
	dataset.forEach(function(k){
		var dmac=k.mac
		var un=devices[dmac].name
		var u_n=clean(un)
		var dip=devices[dmac].ip
		var dn=devices[dmac].device
		var d_n=clean(dn)
		var did='dd-di-'+devices[dmac].id
 		var up=k.up,down=k.down,ul_down=k.ul_down, ul_up=k.ul_up,dt=up+down-(ul_up+ul_down)*ul_redtot
		if (dmac=="FF:FF:FF:FF:FF:FF") { 
			tdaemon=$('<tr/>').attr('id','tdaemon')
			tdaemon.append($('<td/>').addClass('deviceName br a-r').text(dn).attr('title', 'Traff daemon data'))
			tdaemon.append($('<td/>').addClass('downloads num').attr('value',down))
			tdaemon.append($('<td/>').addClass('uploads num br').attr('value',up))
			tdaemon.append($('<td/>').addClass('isUL ul-down').attr('value',ul_down))
			tdaemon.append($('<td/>').addClass('isUL ul-uo br').attr('value',ul_up))
			tdaemon.append($('<td/>').addClass('TotalBytes br2 num').attr('value',dt))
			tdaemon.append($('<td/>').addClass('br'))
			tdaemon_diff=$('<tr/>').attr('id','tdaemon-diff')
			tdaemon_diff.append($('<td/>').addClass('deviceName a-r br').text('difference'))
			tdaemon_diff.append($('<td/>').addClass('downloads num'))
			tdaemon_diff.append($('<td/>').addClass('uploads num br'))
			tdaemon_diff.append($('<td/>').addClass('isUL ul-down'))
			tdaemon_diff.append($('<td/>').addClass('isUL ul-up br'))
			tdaemon_diff.append($('<td/>').addClass('TotalBytes num'))
			tdaemon_diff.append($('<td/>').addClass('br'))
			return 
		}
		else if(dmac=='PROC:NET:DEV'){
			tpnd=$('<tr/>').attr('id','tpnd')
			tpnd.append($('<td/>').addClass('deviceName br a-r').text(dn).attr('title', 'proc/net/data data'))
			tpnd.append($('<td/>').addClass('downloads num').attr('value',down))
			tpnd.append($('<td/>').addClass('uploads num br').attr('value',up))
			tpnd.append($('<td/>').addClass('isUL ul-down'))
			tpnd.append($('<td/>').addClass('isUL ul-up br'))
			tpnd.append($('<td/>').addClass('TotalBytes br2 num').attr('value',dt))
			tpnd.append($('<td/>').addClass('br'))
			tpnd_diff=$('<tr/>').attr('id','tpnd-diff')
			tpnd_diff.append($('<td/>').addClass('deviceName a-r br').text('difference'))
			tpnd_diff.append($('<td/>').addClass('downloads num'))
			tpnd_diff.append($('<td/>').addClass('uploads num br'))
			tpnd_diff.append($('<td/>').addClass('isUL ul-down'))
			tpnd_diff.append($('<td/>').addClass('isUL ul-up br'))
			tpnd_diff.append($('<td/>').addClass('TotalBytes num'))
			tpnd_diff.append($('<td/>').addClass('br'))
			return 
		}
		total+=dt
		utot+=up
		dtot+=down
		ul_utot+=ul_up
		ul_dtot+=ul_down
		if(dnames[un]===undefined){
			dnames[un]={down:0, up:0,ul_down:0, ul_up:0}
		}
		dnames[un].down+=down
		dnames[un].up+=up
		dnames[un].ul_down+=ul_down
		dnames[un].ul_up+=ul_up
		var is_z=dt==0?' is_z':''
		if($("#"+did).length==0){
			var dc='d-un-'+u_n
			var nr=$('<tr/>').attr('id',did).addClass('is_d '+dc+is_z).attr('owner-name',un)
			var tcolour=devices[dmac].colour==null?colours_list[devices[dmac].un]:devices[dmac].colour
			nr.append($('<td/>').addClass('deviceName br').html("<span style='background-color:"+tcolour+"' class='legend-colour' title='Click to add/remove this device from the Hourly Graph below'></span><span class='thedevice'>"+dn+"</span>").attr('title', dmac+' | '+dip))
			nr.append($('<td/>').addClass('downloads num').attr('value',down))
			nr.append($('<td/>').addClass('uploads num br').attr('value',up))
			nr.append($('<td/>').addClass('isUL ul-down num').attr('value',ul_down))
			nr.append($('<td/>').addClass('isUL ul-up num br').attr('value',ul_up))
			nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',dt))
			nr.append($('<td/>').addClass('percent br'))
			if($('.'+dc).length>0){
				 $('.'+dc).last().after(nr)
			}
			else if($('#'+dc).length>0){
				 $('#'+dc).after(nr)
			}
			else{
				$(tag).append(nr)
			}
			$('#'+did+' .thedevice').click(function(){
				$('#mb-filter').val('dd-'+u_n+'-'+d_n).change()
			})
			$('#'+did+' .legend-colour').click(function(){
				if( $('#h_sd-ddl').is(':visible')){$('#h_sd-ddl').slideUp()}
				$('.fd-sel').removeClass('fd-sel')
				var ishidden=$(this).hasClass('op10')
				var dmac=$(this).parent('td').attr('title').split('|')[0].trim()
				hourly[dmac].ishidden=!ishidden
				$(this)[ishidden?'removeClass':'addClass']('op10')
				$(this).next()[ishidden?'removeClass':'addClass']('so')
				DrawHourlyGraph();
			})
		}
		else{
			var arr=[[' .downloads',down], [' .uploads',up], [' .ul-down',ul_down], [' .ul-up',ul_up], [' .TotalBytes',dt]]
			updateRow(did,arr)
		}
	})
 	Object.keys(dnames).forEach(function(k){
		var u_n=clean(k)
		var uid='d-un-'+u_n
		var up=dnames[k].up,down=dnames[k].down,ul_up=dnames[k].ul_up,ul_down=dnames[k].ul_down,ut=up+down-(ul_up+ul_down)*ul_redtot
		var is_z=ut==0?' is_z':''
		if($("#"+uid).length==0){
			var nr=$('<tr/>').attr('id',uid).addClass('is_u'+is_z)
			nr.append($('<td/>').addClass('br td-un').html("<span class='item-e'></span><span class='userName'>" +k+"</span>"))
			nr.append($('<td/>').addClass('downloads num').attr('value',down))
			nr.append($('<td/>').addClass('uploads num br').attr('value',up))
			nr.append($('<td/>').addClass('isUL ul-down num').attr('value',ul_down))
			nr.append($('<td/>').addClass('isUL ul-up num br').attr('value',ul_up))
			nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',ut))
			nr.append($('<td/>').addClass('percent br'))
			$('.'+uid).first().before(nr)
			$('#'+uid+' .userName').click(function(){
				$('#mb-filter').val('dd-'+u_n).change()
			})
		}
		else{
			var arr=[[' .downloads',down], [' .uploads',up],[' .ul-down',ul_down], [' .ul-up',ul_up], [' .TotalBytes',ut]]
			updateRow(uid,arr)
		}
	})
	$('#h_sd-ddl').html("<span id='h_fd-all' class='h_fd'>All</span><span id='h_fd-none' class='h_fd'>None</span>")
	$('#daily-usage-table .userName').each(function(){
		$('#h_sd-ddl').append("<span class='h_fd'>"+$(this).text()+"</span>")
	})
	$('.item-e')[$('#ShowDevices').is(':checked')?'removeClass':'addClass']('item-c')
	$('#daily-usage-table .item-e').unbind('click')
	$('#daily-usage-table .item-e').click(function(){
		var is_e = $(this).hasClass('item-c')
		$(this)[is_e?'removeClass':'addClass']('item-c')
		var un=$(this).siblings('.userName').text()
		$('#daily-usage-table .is_d[owner-name='+un+']')[is_e?'show':'hide']()
		DrawPie('Daily')
	})
	$('.h_fd').click(function(){
		var un=$(this).text()
		$('.fd-sel').removeClass('fd-sel')
		$(this).addClass('fd-sel')
		$('#h_sd-ddl').delay(250).slideUp('slow')
		$('#h_sd-dd').text(un)
		if(un=='All'){
			ShowDevices(1)
		}
		else if(un=='None'){
			 ShowDevices(0)
		}
		else{
			ShowUserDevices(un)
			$('#h_sd-dd').text(un)
		}
	})
	$('#h_sd-ddl').mouseleave(function(){
		$(this).slideUp('slow')
	})
	
	if($('#dailyFooter').html().length==0 && nrd>0){
		var nr=$('#dailyFooter').addClass('footer')
		nr.append($('<td/>').text(':::Totals:::').addClass('a-r br'))
		nr.append($('<td/>').addClass('downloads num').attr('value',dtot))
		nr.append($('<td/>').addClass('uploads num br').attr('value',utot))
		nr.append($('<td/>').addClass('isUL ul-down num').attr('value',ul_dtot))
		nr.append($('<td/>').addClass('isUL ul-up num br').attr('value',ul_utot))
		nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',total))
		nr.append($('<td/>').text('-').addClass('a-c percent br'))
		$('#dailyFooter').append(nr)
	}
	else{
		var arr=[[' .uploads',utot], [' .downloads',dtot], [' .ul-down',ul_dtot], [' .ul-up',ul_utot], [' .TotalBytes',total]]
		updateRow('dailyFooter',arr)
	}
	if(tdaemon.length>0 && _traff_daemon==1){
		$('#dailyFooter').after(tdaemon)
		$('#tdaemon').after(tdaemon_diff)
		$('#tdaemon-diff .downloads').attr('value',$('#tdaemon .downloads').attr('value')-$('#dailyFooter .downloads').attr('value'))
		$('#tdaemon-diff .uploads').attr('value',$('#tdaemon .uploads').attr('value')-$('#dailyFooter .uploads').attr('value'))
		$('#tdaemon-diff .TotalBytes').addClass('br2').attr('value',$('#tdaemon .TotalBytes').attr('value')-$('#dailyFooter .TotalBytes').attr('value'))
	}
	if(tpnd.length>0 && _traff_daemon==1){
		$('#dailyFooter').after(tpnd)
		$('#tpnd').after(tpnd_diff)
		$('#tpnd-diff .downloads').attr('value',$('#tpnd .downloads').attr('value')-$('#dailyFooter .downloads').attr('value'))
		$('#tpnd-diff .uploads').attr('value',$('#tpnd .uploads').attr('value')-$('#dailyFooter .uploads').attr('value'))
		$('#tpnd-diff .TotalBytes').addClass('br2').attr('value',$('#tpnd .TotalBytes').attr('value')-$('#dailyFooter .TotalBytes').attr('value'))
	}
	$('.isUL')[_unlimited_usage==1?'show':'hide']()
	changelegend()
	setPercents('#DailyData tr, #correction-row', total)
	displayBytes('#daily-usage-table');
	$('#no-daily-data')[nrd==0?'slideDown':'slideUp']('slow')
	$('#daily-tab-section .changes-legend,#dailyFooter')[nrd==0?'slideUp':'slideDown']('slow')
}

function changelegend(){
	$('#changes-legend')[$('table .changed').length==0?'slideUp':'slideDown']('slow')
	$('#changes-legend .c0')[$('table .changed.c0').length==0?'hide':'show']()
	$('#changes-legend .c1')[$('table .changed.c1').length==0?'hide':'show']()
	$('#changes-legend .c2')[$('table .changed.c2').length==0?'hide':'show']()
	$('#changes-legend .c3')[$('table .changed.c3').length==0?'hide':'show']()
	$('#changes-legend .c4')[$('table .changed.c4').length==0?'hide':'show']()
	$('#changes-legend .c5')[$('table .changed.c5').length==0?'hide':'show']()

}
function setMonthlyTab(){
	var tag=$("#MonthlyData");
	var total=0,utot=0,dtot=0, traff_u=0,traff_d=0, pnd_u=0,pnd_d=0,ul_utot=0,ul_dtot=0
	$('#mtdaemon, #mtdaemon-diff').remove()
	var ul_redtot=$('#ul-redtot-y').is(':checked')
	Object.keys(devices).sort(byName).forEach(function(k){
		var up=devices[k].up,down=devices[k].down,ul_down=devices[k].ul_down,ul_up=devices[k].ul_up,dt=up+down-(ul_up+ul_down)*ul_redtot
		if(k=='FF:FF:FF:FF:FF:FF'){
			traff_u+=up
			traff_d+=down
			return
		}
		else if(k=='PROC:NET:DEV'){
			pnd_u+=up
			pnd_d+=down
			return
		}
		total+=dt
		utot+=up
		dtot+=down
		ul_utot+=ul_up
		ul_dtot+=ul_down
		var is_z=dt==0?' is_z':''
		var did='mt-di-'+devices[k].id
		if($("#"+did).length==0){
			var un=devices[k].name
			var dn=devices[k].device
			var u_n=clean(un)
			var d_n=clean(dn)
			var tcolour=devices[k].colour==null?colours_list[devices[k].un]:devices[k].colour
			var nr=$('<tr/>').attr('id',did).addClass('is_d un-'+u_n+is_z).attr('owner-name',un)
			nr.append($('<td/>').addClass('deviceName br').html("<span class='legend-colour' style='background:"+tcolour+"'></span><span class='thedevice'>"+dn+"</span>").attr('title', k+' | '+devices[k].ip))
			nr.append($('<td/>').addClass('downloads num').attr('value',down))
			nr.append($('<td/>').addClass('uploads num br').attr('value',up))
			nr.append($('<td/>').addClass('isUL ul-down num').attr('value',ul_down))
			nr.append($('<td/>').addClass('isUL ul-up num br').attr('value',ul_up))
			nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',dt))
			nr.append($('<td/>').addClass('percent br'))
			$(tag).append(nr)
			$('#'+did+' .thedevice').click(function(){
				$('#mb-filter').val('dd-'+u_n+'-'+d_n).change()
			})
		}
		else{
			var arr=[[' .downloads',down], [' .uploads',up], [' .TotalBytes',dt]]
			updateRow(did,arr)
		}
	})
	Object.keys(names).forEach(function(k){
		var u_n=clean(k)
		var uid='mt-un-'+u_n
		var up=names[k].up,down=names[k].down,ul_down=names[k].ul_down,ul_up=names[k].ul_up,ut=up+down-(ul_up+ul_down)*ul_redtot
		var is_z=ut==0?' is_z':''
		if($("#"+uid).length==0){
			var nr=$('<tr/>').attr('id',uid).addClass('is_u').addClass(is_z)
			nr.append($('<td/>').addClass('br').html("<span class='item-e'></span><span class='userName'>" +k+"</span>"))
			nr.append($('<td/>').addClass('downloads num').attr('value',down))
			nr.append($('<td/>').addClass('uploads num br').attr('value',up))
			nr.append($('<td/>').addClass('isUL ul-down num').attr('value',ul_down))
			nr.append($('<td/>').addClass('isUL ul-up num br').attr('value',ul_up))
			nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',ut))
			nr.append($('<td/>').addClass('percent br'))
			$('.un-'+u_n).first().before(nr)
			$('#'+uid+' .userName').click(function(){
				$('#mb-filter').val('dd-'+u_n).change()
			})
		}
		else{
			var arr=[[' .uploads',up], [' .downloads',down], [' .TotalBytes',ut]]
			updateRow(uid,arr)
		}
	})
	$('.item-e')[$('#ShowDevices').is(':checked')?'removeClass':'addClass']('item-c')
	$('#monthly-usage-table .item-e').unbind('click')
	$('#monthly-totals-table .item-e').click(function(){
		var is_e = $(this).hasClass('item-c')
		var s_z=$('#ShowZeroes').is(':checked')?'':'.is_z'
		$(this)[is_e?'removeClass':'addClass']('item-c')
		var un=$(this).siblings('.userName').text()
		$('#monthly-totals-table .is_d[owner-name='+un+']').not(s_z)[is_e?'show':'hide']()
		DrawPie('Monthly')
		if(_unlimited_usage=='1'){
			DrawPie('Unlimited')
		}
	})
	var c_up=0,c_down=0
	for(var d in corrections){
		if(corrections[d]){
			c_up+=corrections[d].up*toMB
			c_down+=corrections[d].down*toMB
	   }
	}
	$('#mcorrection-row .uploads').attr('value',c_up)
	$('#mcorrection-row .downloads').attr('value',c_down)
	$('#mcorrection-row .TotalBytes').attr('value',c_up+c_down)

	dtot+=c_down
	utot+=c_up
	total+=c_down+c_up

	if($('#monthlyFooter').html().length==0){
		var nr=$('#monthlyFooter').addClass('footer')
		nr.append($('<td/>').text(':::Totals:::').addClass('a-r br'))
		nr.append($('<td/>').addClass('downloads num').attr('value',dtot))
		nr.append($('<td/>').addClass('uploads num br').attr('value',utot))
		nr.append($('<td/>').addClass('isUL ul-down num').attr('value',ul_utot))
		nr.append($('<td/>').addClass('isUL ul-up num br').attr('value',ul_dtot))
		nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',total))
		nr.append($('<td/>').text('-').addClass('a-c percent'))
		$('#monthlyFooter').append(nr)
	}
	else{
		var arr=[[' .downloads',dtot], [' .uploads',utot], [' .ul-down',dtot], [' .ul-up',utot], [' .TotalBytes',total]]
		updateRow('monthlyFooter',arr)
	}
	
	if(_traff_daemon==1){
		var tdaemon=$('<tr/>').attr('id','mtdaemon')
		tdaemon.append($('<td/>').addClass('deviceName br a-r').text('traff daemon'))
		tdaemon.append($('<td/>').addClass('downloads num').attr('value',traff_d))
		tdaemon.append($('<td/>').addClass('uploads num br').attr('value',traff_u))
		tdaemon.append($('<td/>').addClass('isUL'))
		tdaemon.append($('<td/>').addClass('isUL br'))
		tdaemon.append($('<td/>').addClass('TotalBytes br2 num').attr('value',traff_d+traff_u))
		tdaemon.append($('<td/>').addClass(''))
		var tdaemon_diff=$('<tr/>').attr('id','mtdaemon-diff')
		tdaemon_diff.append($('<td/>').addClass('deviceName br a-r').text('difference'))
		tdaemon_diff.append($('<td/>').addClass('downloads num'))
		tdaemon_diff.append($('<td/>').addClass('uploads num br'))
		tdaemon_diff.append($('<td/>').addClass('isUL'))
		tdaemon_diff.append($('<td/>').addClass('isUL br'))
		tdaemon_diff.append($('<td/>').addClass('TotalBytes br2 num'))
		tdaemon_diff.append($('<td/>').addClass(''))
		$('#monthlyFooter').after(tdaemon)
		$('#mtdaemon').after(tdaemon_diff)
		$('#mtdaemon-diff .downloads').attr('value',$('#mtdaemon .downloads').attr('value')-$('#monthlyFooter .downloads').attr('value'))
		$('#mtdaemon-diff .uploads').attr('value',$('#mtdaemon .uploads').attr('value')-$('#monthlyFooter .uploads').attr('value'))
		$('#mtdaemon-diff .TotalBytes').attr('value',$('#mtdaemon .TotalBytes').attr('value')-$('#monthlyFooter .TotalBytes').attr('value'))
	}

	$('.isUL')[_unlimited_usage==1?'show':'hide']()
	setPercents('#MonthlyData tr,#mcorrection-row', total)
	displayBytes('#monthly-totals-table');
}
function clean(n){
	return n.replace(' ','_').replace(/\W/g, "")
}
function updateRow(did,arr){
	arr.forEach(function(i){
		updateValue('#'+did+i[0],i[1])
	})
}
function updateValue(vid,v){
	var base=$("#DisplayBase").val();
	var delta=v-$(vid).attr('value')
	if(delta!=0){
		var deltaIndex=Math.floor(Math.log(Math.abs(delta))/Math.log(base));
		var delta_val=(delta/Math.pow(base,Math.floor(deltaIndex))).toFixed(_dec);
		var units=dispUnits[deltaIndex]+'ytes';
		var nstars=Math.floor(Math.log(delta)/Math.log(base));
		var msg='delta: '+delta_val + ' ' + units
		$(vid).attr('value',v).addClass('changed c'+nstars).attr('title',msg)
	}
}
function DrawPie(m_d){
	var rn=0;
	var ch_title=(m_d=='Unlimited')
		?('Usage by User and/or Device during\n`Unlimited` interval (i.e., between '+_unlimited_start+' - '+_unlimited_end+')')
		:(m_d+' Usage by User and/or Device\n(' + ($('#ul-redtot-y').is(':checked')?'less':'including') + ' `Unlimited` usage between '+_unlimited_start+' - '+_unlimited_end+')')
	var options={width:500,height:300,title: ch_title,is3D:true,slices:{},colors:{},chartArea:{left:180}};
	var data, datarows=[],devicecolours=[],tmp, mac
	var showexploded=false
	var colours=[]
	var wt=(m_d=='Unlimited')?'Monthly':m_d
	data=new google.visualization.DataTable();
	data.addColumn('string','User/Device');
	data.addColumn('number','MB Used');
	$('#'+wt+'Data tr:visible').each(function(){
		if($(this).hasClass('is_u')&&$(this).find('.item-e.item-c').length==0){
			return;
		}
		if($(this).hasClass('is_u')){
			showexploded=true
			var pn=$(this).find('.userName').text()
			colours.push(colours_list[names[pn].n+64])
		}
		else if($(this).hasClass('is_d')){
			var pn=$(this).attr('owner-name')+'-'+$(this).find('.thedevice').text()
			options.slices[rn]={offset:0.33}
			var tmp=$(this).find('.deviceName').attr('title').split('|');
			var mac=tmp[0].trim().toUpperCase();
			var tcolour=devices[mac].colour==null?colours_list[devices[mac].un]:devices[mac].colour
			colours.push(tcolour)
		}
		var ca=((m_d=='Unlimited')?(Number($(this).find('.ul-down').attr('value'))+Number($(this).find('.ul-up').attr('value'))):($(this).find('.TotalBytes').attr('value'))/toMB).toFixed(_dec)
		datarows.push([pn, parseFloat(ca)])
		rn++
	})

	if((m_d=='Daily') && ($('#correction-row .TotalBytes ').attr('value')!=0)){
		var ca=($('#correction-row .TotalBytes ').attr('value')/toMB).toFixed(_dec)
		datarows.push(['Corrections', parseFloat(ca)])
	}
	else if((m_d=='Monthly') && ($('#mcorrection-row .TotalBytes ').attr('value')!=0)){
		var ca=($('#mcorrection-row .TotalBytes ').attr('value')/toMB).toFixed(_dec)
		datarows.push(['Corrections', parseFloat(ca)])
	}
	data.addRows(datarows);
	if(!($('#'+m_d+'Graph').is(':visible')))$('#'+m_d+'Graph').show()
	var ChartObj=new google.visualization.PieChart(document.getElementById(m_d+'Graph'));
	if(!showexploded){
		Object.keys(options.slices).forEach(function(k){
			options.slices[k].offset=0;
		})
	}
	options.colors=colours
	ChartObj.draw(data,options);

}
function monthlyBreakdown(){
	var tag=$("#MonthlyBreakdown");
	var total=0,utot=0,dtot=0,traff_u=0,traff_d=0,pnd_u=0,pnd_d=0
	$('#mb-tdaemon, #mb-tdaemon-diff').remove()
	$('#mbd-graphs .graphs').hide()
	var mb_dates=[],traff=[],pnd=[]
	var syr=_rs_Date.getFullYear()
	var smo=_rs_Date.getMonth()

	var mbfs=$("#mb-filter option:selected")
	var un=mbfs.val().split('-')[1];
	
	if(mbfs.hasClass('ddl-u')){
		var dataset=getUsage('name',$("#mb-filter option:selected").text())
	}
	else if(mbfs.hasClass('ddl-d')){
		var id=(mbfs.attr('id')).replace('mbd-','')
		var mac=getDevice('id',id)
		var dataset=getUsage('mac',mac)
	}
	else{
		var dataset=usage
	}
	var showISP=$('#showISP').is(':checked')&&(un=== "ALL");
	var cap=Number($('#bw_cap').val());

	var sd=new Date(_rs_Date.getFullYear(), _rs_Date.getMonth(), _rs_Date.getDate())
	for (var d = sd; d <= _re_Date; d.setDate(d.getDate() + 1)) {
	
		var ds=d.getFullYear()+'-'+twod(d.getMonth()+1)+'-'+twod(d.getDate())
		var fd=new Date(d.getFullYear(), d.getMonth(), d.getDate())
		mb_dates[ds]={dd:fd,down:0, up:0}
	}

	dataset.forEach(function(k){
		var up=k.up,down=k.down,mbtot=up+down
		var day=k.date
		var mo=Number(day)>=_resetDay?smo:(smo-(-1))
		var dt=new Date(syr,mo,day)
		var ds=syr+'-'+twod(mo+1)+'-'+twod(day)
		if(k.mac=='FF:FF:FF:FF:FF:FF'){
			traff_u+=up
			traff_d+=down
			traff[ds]={dd:dt,down:down, up:up}
			return
		}
		else if(k.mac=='PROC:NET:DEV'){
			pnd_u+=up
			pnd_d+=down
			pnd[ds]={dd:dt,down:down, up:up}
			return
		
		}
		total+=mbtot
		utot+=up
		dtot+=down
		if(mb_dates[ds]===undefined){
			mb_dates[ds]={dd:dt,down:0, up:0}
		}
		mb_dates[ds].down+=down
		mb_dates[ds].up+=up
	})

	if(un=== "ALL"){
		for(var day in corrections){
			if(corrections[day]){
				var c_u=corrections[day].up*1
				var c_up=c_u*toMB
				var c_d=corrections[day].down*1
				var c_down=c_d*toMB
				var mo=Number(day)>=_resetDay?smo:(smo-(-1))
				var dt=new Date(syr,mo,day)
				var ds=syr+'-'+twod(mo+1)+'-'+twod(day)
				total+=c_up+c_down
				utot+=c_up
				dtot+=c_down
				if(mb_dates[ds]===undefined){
					mb_dates[ds]={dd:dt,down:0, up:0}
				}
				mb_dates[ds].down+=c_down
				mb_dates[ds].up+=c_up
				mb_dates[ds].hasCorrection=true
				mb_dates[ds].desc=corrections[day].desc+' (download -> '+c_d+'MB; upload -> '+c_u+'MB)'

		   }
		}
	}
	var cTot=0,ls_u,ls_d,ls_t=0,ls_ut=0,ls_dt=0,ls_ct=0,td_u=0,td_d=0,td_tot=0,td_ct=0,td_di=0,td_cdi=0
	Object.keys(mb_dates).sort(function(a, b) { return (mb_dates[a].dd > mb_dates[b].dd?1:(mb_dates[a].dd < mb_dates[b].dd?-1:0)) }).forEach(function(d){
		var uid='mb-d-'+d
		var up=mb_dates[d].up,down=mb_dates[d].down,dt=up+down
		cTot+=dt
		var is_z=dt==0?' is_z':''
		
		var od=d.split('-')
		var odf=od[0]+'-'+Number(od[1])+'-'+od[2]
		if(Number(od[1])<10 && localStorage.getItem('isp-'+odf)){
			localStorage.setItem('isp-'+d,localStorage.getItem('isp-'+odf))
			localStorage.removeItem('isp-'+odf)
		}
		if(localStorage.getItem('isp-'+d)){
			var ls_data = localStorage.getItem('isp-'+d).split(';')
			ls_u=Number(ls_data[0])
			ls_d=Number(ls_data[1])
		}
		else{
			ls_u=0
			ls_d=0
		}
		if(traff[d]){
			td_u=Number(traff[d].up)
			td_d=Number(traff[d].down)
		}
		else{
			td_u=0
			td_d=0
		}
		td_ct+=(td_u+td_d)

		ls_ut+=ls_u*toMB
		ls_dt+=ls_d*toMB
		ls_t=(ls_u+ls_d)*toMB
		ls_ct+=ls_t
		td_tot= td_d+td_u
		td_di=td_tot==0 ? 0 : td_tot-dt
		td_cdi+=td_di
		var dtot = ls_t-dt;
		var isp=((dtot>0?dtot:0)/toGB).toFixed(2)
		var router=((dtot>0?0:dtot)/toGB).toFixed(2)
		var diff=(ls_ct-cTot)/toGB.toFixed(2)

		if($("#"+uid).length==0){
			var nr=$('<tr/>').attr('id',uid).addClass('mb-row'+is_z)
			var da=mb_dates[d].dd.getDate()
			var mo=mb_dates[d].dd.getMonth()+1
			var yr=mb_dates[d].dd.getFullYear()
			nr.append($('<td/>').addClass('mbd-date a-r br').text(mb_dates[d].dd.toDateString()).attr('value',yr+'-'+mo+'-'+da).attr('title',mb_dates[d].desc))
			nr.append($('<td/>').addClass('downloads num').attr('value',down==0?'-':down))
			nr.append($('<td/>').addClass('uploads num br').attr('value',up==0?'-':up))
			nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',dt==0?'-':dt))
			nr.append($('<td/>').addClass('aggTot num br2').attr('value',dt==0?'-':cTot))

			nr.append($('<td/>').addClass('isp isp-d MBytes').html("<input type='text' value='"+ls_d+"' name='ispd-"+da+"'>"))
			nr.append($('<td/>').addClass('isp isp-u MBytes br').html("<input type='text' value='"+ls_u+"' name='ispu-"+da+"'>"))
			nr.append($('<td/>').addClass('isp isp-t num br2').attr('value',ls_t==0?'-':ls_t))
			nr.append($('<td/>').addClass('isp isp-ct num br2').attr('value',ls_t==0?'-':ls_ct))
			nr.append($('<td/>').addClass('isp isp-di num br').attr('value',ls_t==0?'-':(ls_t-dt)))
			nr.append($('<td/>').addClass('isp isp-cdi num br2').attr('value',ls_t==0?'-':(ls_ct-cTot)))
			
			if(_traff_daemon=='1'){
				nr.append($('<td/>').addClass('is_td td-d num').attr('value',td_d==0?'-':td_d))
				nr.append($('<td/>').addClass('is_td td-u num br').attr('value',td_u==0?'-':td_u))
				nr.append($('<td/>').addClass('is_td td-t num br2').attr('value',td_tot==0?'-':td_tot))
				nr.append($('<td/>').addClass('is_td td-ct num num br2').attr('value',td_tot==0?'-':td_ct))
				nr.append($('<td/>').addClass('is_td td-di num br').attr('value',td_tot==0?'-':td_di))
				nr.append($('<td/>').addClass('is_td td-cdi num br2').attr('value',td_tot==0?'-':td_cdi))
			}
			$('#MonthlyBreakdown').append(nr)
		}
		else{
			var arr=[[' .downloads',down], [' .uploads',up], [' .TotalBytes',dt], [' .aggTot',cTot]]
			updateRow(uid,arr)
		}
		$('#'+uid+' .mbd-date')[mb_dates[d].hasCorrection==true?'addClass':'removeClass']('corrected')
	})

	if($('#breakdownFooter').html().length==0){
		var nr=$('<tr/>').attr('id','bdFooter').addClass('footer')
		nr.append($('<td/>').text(':::Totals:::').addClass('a-r br'))
		nr.append($('<td/>').addClass('downloads num').attr('value',dtot))
		nr.append($('<td/>').addClass('uploads num br').attr('value',utot))
		nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',total))
		nr.append($('<td/>').text('-').addClass('a-c br2'))
		nr.append($('<td/>').addClass('isp num').attr('value',ls_dt).attr('id','isp-dt'))
		nr.append($('<td/>').addClass('isp num br').attr('value',ls_ut).attr('id','isp-ut'))
		nr.append($('<td/>').addClass('isp num br2').attr('value',ls_ct).attr('id','isp-t'))
		nr.append($('<td/>').text('-').addClass('isp a-c br2'))
		nr.append($('<td/>').text('-').addClass('isp a-c br'))
		nr.append($('<td/>').addClass('isp isp-cdi GBytes num br2').attr('value',ls_ct-cTot))
		if(_traff_daemon==1){
			nr.append($('<td/>').addClass('is_td num').attr('value',traff_d))
			nr.append($('<td/>').addClass('is_td num br').attr('value',traff_u))
			nr.append($('<td/>').addClass('is_td td-t num br2').attr('value',traff_d+traff_u))
			nr.append($('<td/>').text('-').addClass('is_td a-c br2'))
			nr.append($('<td/>').text('-').addClass('is_td a-c br'))
			nr.append($('<td/>').addClass('is_td td-cdi num br2').attr('value',td_cdi))
		}
		$('#breakdownFooter').append(nr)
	}
	else{
		var arr=[[' .downloads',dtot], [' .uploads',utot], [' .TotalBytes',total]]
		updateRow('bdFooter',arr)
		updateISPTotals()
	}

	$('.is_td')[(_traff_daemon=='1' && un=='ALL')?'show':'hide']()
	displayBytes('#MonthlyBreakdown,#breakdownFooter');

	if(showISP){
		ISP_Change()
	}
	$('.correction-note')[$('tr .corrected').length==0?'hide':'show']()
	$('.mbd-date').click(function(){
		var dt=$(this).attr('value').split('-')
		_cr_Date=new Date(dt[0],dt[1]-1,dt[2])
		$('#daily-tab').removeClass('loaded');
		load_view('daily-tab',true);
	})
	
	drawGraphs()
	
}
function drawGraphs(){
	var mbfs=$("#mb-filter option:selected")
	var un=mbfs.val().split('-')[1];
	
	if(un==='ALL'){
		var gr4='All Devices for All Users'
	}
	else if($(mbfs).hasClass('ddl-u')){
		var gr4='All Devices for User: `'+un+'`'
	}
	else{
		var dn=mbfs.text();
		var gr4='Device: `'+dn+'` for User: `'+un+'`'
	}
	$('#graphsfor').text(gr4)
	$('.gr-nall')[un==='ALL'&&($('#showISP').is(':checked')||(_traff_daemon=='1'))?'show':'hide']()
   
	var bd_graphs=JSON.parse(localStorage["bd_graphs"])
	for (var k in bd_graphs){
		DrawGraph(bd_graphs[k][0])
	} 
}
function DrawGraph(wg){
	if(!$('#'+wg).parents('label').is(':visible')) return
	$('#gr-'+wg)[$('#'+wg).is(':checked')?'show':'hide']()
	if(!$('#'+wg).is(':checked'))return
   
	var w_ya='.'+wg, cn='',w_yu, w_yd, w_isp, w_td,is_val=false,is_pct=false,noyamon=false,is_cpct=false,is_tot=(wg=='cb-tot'),ct,g_sc,gr_scale,loc='column'
	var mbfs=$("#mb-filter option:selected")
	var un=mbfs.val().split('-')[1];
	var dec=_dec
	switch (wg) {
		case 'cb-down':
			ct='Downloads by Day'
			w_td='.td-d'
			w_isp='.isp-d input'
			gr_scale=setGraphScale('downloads')
			cn='Downloads'
			w_ya='.downloads'
			break;
		case 'cb-up':
			ct='Uploads by Day'
			w_td='.td-u'
			w_isp='.isp-u input'
			gr_scale=setGraphScale('uploads')
			cn='Uploads'
			w_ya='.uploads'
			break;
		case 'cb-tot':
			ct='Total Traffic by Day'
			w_yu='.uploads'
			w_yd='.downloads'
			w_td='.td-t'
			w_isp='.isp-t'
			gr_scale=setGraphScale('TotalBytes')
			is_val=true
			break;
	   case 'cb-cum':
			ct='Cumulative Traffic'
			w_ya='.aggTot'
			w_td='.td-ct'
			w_isp='.isp-ct'
			gr_scale=setGraphScale('TotalBytes')
			is_val=true
			loc='column'
			cn='Cumulative'
			break;
	   case 'cb-dif':
			ct='Absolute Differences from YAMon'
			dec=2
			w_ya='.0 '
			w_td='.td-di'
			w_isp='.isp-di'
			gr_scale='MB'
			is_val=true
			noyamon=true
			break;
	   case 'cb-difp':
			ct='Relative Differences from YAMon'
			dec=2
			var y_d='.downloads'
			var y_u='.uploads'
			var td_d='.td-d'
			var td_u='.td-u'
			var isp_d='.isp-d input'
			var isp_u='.isp-u input'
			w_isp='.isp-di'
			gr_scale='%'
			is_val=true
			is_pct=true
			noyamon=true
			break;
	   case 'cb-cdif':
			ct='Cumulative Difference from YAMon '
			w_ya='.0 '
			w_td='.td-cdi'
			w_isp='.isp-cdi'
			gr_scale=setGraphScale('td-cdi')
			is_val=true
			noyamon=true
			break;
	   case 'cb-cdifp':
			ct='Cumulative Difference from YAMon '
			w_ya='.aggTot'
			w_td='.td-cdi'
			w_isp='.isp-cdi'
			gr_scale='%'
			is_cpct=true
			noyamon=true
			break;
	}
	g_sc=gr_scale=='%'?1:(gr_scale=='GB'?toGB:(gr_scale=='MB'?toMB:toKB))

	var data=new google.visualization.DataTable();
	var options={width:1000,height:400,title:ct+' (in '+gr_scale+')',legend:{position:'top'},isStacked:true,hAxis:{textStyle:{fontSize:7},title:$('.current-interval').first().text(),slantedText:true,titleTextStyle:{f:'green'}},vAxes:{0:{title:gr_scale,titleTextStyle:{color:'green'}}},series:{}};
	var gseries=[]
	var yd_colour='mediumblue',yu_colour='mediumturquoise',y_colour='blue'
	data.addColumn('string','Day');
	if(is_tot){
		data.addColumn('number','YAMon Downloads');
		data.addColumn('number','YAMon Uploads');
		gseries.push({color:yd_colour,type:'column',visibleInLegend:true,targetAxisIndex:0})
		gseries.push({color:yu_colour,type:'column',visibleInLegend:true,targetAxisIndex:0})
	}
	else if (noyamon){}
	
	else{
		var y_colour=(wg=='cb-down'?yd_colour:(wg=='cb-up'?yu_colour:y_colour))
		data.addColumn('number','YAMon - '+cn);
		gseries.push({color:y_colour,type:loc,visibleInLegend:true,targetAxisIndex:0})
	}
	var inc_isp=$('#showISP').is(':checked')&& un==='ALL'
	var inc_traff=_traff_daemon=='1'&& un==='ALL'
	
	if(is_pct && inc_traff){
		data.addColumn('number','Traff Downloads');
		data.addColumn({type: 'boolean', role: 'certainty'});
		data.addColumn('number','Traff Uploads');
		data.addColumn({type: 'boolean', role: 'certainty'});
		gseries.push({color:'green',type:'line',visibleInLegend:true,targetAxisIndex:0})
		gseries.push({color:'limegreen',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	else if(is_cpct && inc_traff){
	   data.addColumn('number','Traff');
		gseries.push({color:'green',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	else if(inc_traff){
		data.addColumn('number','Traff');
		gseries.push({color:'green',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	var ispname=$('#isp-name').val()||'ISP'
	if(is_pct && inc_isp){
		data.addColumn('number',ispname+' Downloads');
		data.addColumn({type: 'boolean', role: 'certainty'});
		data.addColumn('number',ispname+' Uploads');
		data.addColumn({type: 'boolean', role: 'certainty'});
		gseries.push({color:'red',type:'line',visibleInLegend:true,targetAxisIndex:0})
		gseries.push({color:'deeppink',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	else if(is_cpct && inc_isp){
		data.addColumn('number',ispname);
		gseries.push({color:'red',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	else if(inc_isp){
		data.addColumn('number',ispname);
		gseries.push({color:'red',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	var inc_bw_cap=wg=='cb-cum' && $('#bandwidth-l').is(':checked') && $('#mb-filter option:selected').text().split(' ')[0]=='ALL'
	if(inc_bw_cap){
		data.addColumn('number','Bandwidth Cap');
		var bw_cap=Number(($('#bw_cap').val()*toGB/g_sc).toFixed(dec))
		gseries.push({color:'purple',type:'line',visibleInLegend:true,targetAxisIndex:0})
	}
	$('.mb-row').each(function(){
		var dt=$(this).attr('id').replace('mb-d-','')
		var row_data=[]
		row_data.push(dt)
		
		if(is_tot){
			var yu=Number(($(this).find(w_yu).attr('value')/g_sc).toFixed(dec))
			var yd=Number(($(this).find(w_yd).attr('value')/g_sc).toFixed(dec))
			row_data.push(yd)
			row_data.push(yu)
		}
		else if(noyamon){}
		else{
			var yamon=Number(($(this).find(w_ya).attr('value')/g_sc).toFixed(dec))
			row_data.push(yamon)
		}
		if(is_pct && inc_traff){
			var td=$(this).find(td_d).attr('value')
			var yd=$(this).find(y_d).attr('value')
			var p_d=Number(((td-yd)/yd*100).toFixed(dec))
			row_data.push(p_d,true)
			var tu=$(this).find(td_u).attr('value')
			var yu=$(this).find(y_u).attr('value')
			var p_u=Number(((tu-yu)/yu*100).toFixed(dec))
			row_data.push(p_u,false)
		}
		else if(is_cpct && inc_traff){
			var td=$(this).find(w_td).attr('value')
			var yd=$(this).find(w_ya).attr('value')
			var p_d=Number((td/yd*100).toFixed(dec))
			row_data.push(p_d)
		}
		else if(inc_traff){
			var traff=Number(($(this).find(w_td).attr('value')/g_sc).toFixed(dec))
			row_data.push(traff)
		}
		if(is_pct && inc_isp){
			var td=$(this).find(isp_d).val()*toMB
			var yd=$(this).find(y_d).attr('value')
			var p_d=Number(((td-yd)/yd*100).toFixed(dec))
			row_data.push(td==0?null:p_d,true)
			var tu=$(this).find(isp_u).val()*toMB
			var yu=$(this).find(y_u).attr('value')
			var p_u=Number(((tu-yu)/yu*100).toFixed(dec))
			row_data.push(tu==0?null:p_u,false)
		}
		else if(is_cpct && inc_isp){
			var td=$(this).find(w_isp).attr('value')
			var yd=$(this).find(w_ya).attr('value')
			var p_d=Number((td/yd*100).toFixed(dec))
			row_data.push(p_d)
		}
	   else if(inc_isp){
			var cv=is_val?$(this).find(w_isp).attr('value'):$(this).find(w_isp).val()
			var isp=Number((cv*(is_val?1:toMB)/g_sc).toFixed(dec))
			row_data.push(cv=='-'||cv==0?null:isp)
		}
		if(inc_bw_cap){
			row_data.push(bw_cap)
		}
		data.addRow(row_data)
	})
	$('#gr-'+wg).slideDown()
	var chart=new google.visualization.ColumnChart(document.getElementById('gr-'+wg));
	options['series']=gseries
	chart.draw(data, options);
}
function setGraphScale(range){
	var gr=$('#bdFooter .' + range)
	if(gr.hasClass('GBytes')&&Number(gr.text()>10)) return 'GB'
	if(gr.hasClass('GBytes')) return 'MB'
	if(gr.hasClass('MBytes')&&Number(gr.text()>10)) return 'MB'
	return 'KB'

}
function UsageHistoryChart(){
	if($('.summary-row').length==1) return;
	var g_usage=[]
	if($('#bandwidth-l').is(':checked')){
		 var cap=Number($('#bw_cap').val())
	}
	$('.summary-row').each(function(){
		var t=$(this).attr('id').split('-')
		var cI=t[2]+'-'+t[3]
		var up=Number(($(this).find('.uploads').attr('value')/toGB).toFixed(_dec))
		var down=Number(($(this).find('.downloads').attr('value')/toGB).toFixed(_dec))
		if($('#bandwidth-l').is(':checked')){
			g_usage.push([cI,down,up,cap]);
		}
		else{
			g_usage.push([cI,down,up]);
		}
	})
	var data;
	data=new google.visualization.DataTable();
	data.addColumn('string','Billing Interval');
	data.addColumn('number','Downloads');
	data.addColumn('number','Uploads');
	if($('#bandwidth-l').is(':checked')){
		data.addColumn('number','Usage Allowance');
	}
	data.addRows(g_usage.reverse());
	var ht=$('#summary-tab-section').height()
	var baroptions={
		width:400,height:ht,seriesType: "bars",title:'Monthly Utilization',legend:{position:'top'},chartArea:{width:'80%',height:'40%'},isStacked:true,hAxis:{title:'Month',slantedText:true,titleTextStyle:{color:'green'}},vAxis:{title:'GB',titleTextStyle:{color:'green'}},series:{0:{color:'blue',visibleInLegend:true},1:{color:'green',visibleInLegend:true},2:{type: "line",color:'red',visibleInLegend:true}}
	};
	var UsageChart=new google.visualization.ColumnChart(document.getElementById('UsageGraph'));
	UsageChart.draw(data,baroptions);
}
function ISP_Change(){
	$('.isp')[$('#showISP').is(':checked')?'show':'hide']()
	drawGraphs()
	$('.isp-u input, .isp-d input').unbind('change').change(function(){
		$(this).removeClass('badvalue');
		if(isNaN($(this).val())){
			$(this).addClass('badvalue');
			$(this).select();
		}
		else{
			var row=$(this).parents('tr');
			var row_id=row.attr('id').split('-');
			var isp_date=row_id[2] + '-' + row_id[3] + '-' + row_id[4];
			var isp_u=Number(row.find('.isp-u input').val())
			var isp_d=Number(row.find('.isp-d input').val())
			var tb =Number(row.find('.TotalBytes ').attr('value'))
			var tot=(isp_u+isp_d)*toMB
			row.find('.isp-t').attr('value',(tot).toFixed(0))
			row.find('.isp-di').attr('value',(tot-tb))
			displayBytes('#MonthlyBreakdown');
			var isp_data=isp_u+';'+isp_d
			localStorage.setItem('isp-'+isp_date,isp_data)
			updateISPTotals()
			drawGraphs()
		}
	})
	drawGraphs()
}
function updateISPTotals(){
	var tu=0,td=0
	$('.mb-row').each(function(){
		var dd=$(this).find('.isp-d input').val()*toMB,du=$(this).find('.isp-u input').val()*toMB
		tu+=du
		td+=dd
	})
	$('#isp-dt').attr('value',td)
	$('#isp-ut').attr('value',tu)
	$('#isp-t').attr('value',td+tu)
	displayBytes('#breakdownFooter');

}
function byName(a,b) {
	var n1=devices[a].name.toLowerCase()
	var n2=devices[b].name.toLowerCase()
	return ((n1<n2)?-1:((n1>n2)?1:byDevice(a,b)));
}
function byDevice(a, b) {
	var d1=devices[a].device.toLowerCase()
	var d2=devices[b].device.toLowerCase()
	return ((d1<d2)?-1:((d1>d2)?1:0));
}
function setDevicesTab(){
	var tag=$("#devicesData");
	var total=0
	Object.keys(devices).sort(byName).forEach(function(k){
		if(k=='FF:FF:FF:FF:FF:FF')return
		if(k=='PROC:NET:DEV')return
		var dt=devices[k].up+devices[k].down
		total+=dt
		var is_z=dt==0?' is_z':''
		var did='dt-'+devices[k].id
		if($('#'+did).length==0){
			var un=devices[k].name
			var dn=devices[k].device
			var u_n=clean(un)
			var d_n=clean(dn)
			var nr=$('<tr/>').attr('id',did).addClass('is_d').addClass(is_z)
			nr.append($('<td/>').addClass('userName').text(devices[k].name))
			nr.append($('<td/>').addClass('deviceName').text(devices[k].device))
			nr.append($('<td/>').addClass('deviceIP').text(devices[k].ip))
			nr.append($('<td/>').addClass('deviceMAC').text(k))
			nr.append($('<td/>').addClass('TotalBytes br2 num').attr('value',dt))
			nr.append($('<td/>').addClass('percent br'))
			$(tag).append(nr)
			$('#'+did+' .userName').click(function(){
				$('#mb-filter').val('dd-'+u_n).change()
			})
		   $('#'+did+' .deviceName').click(function(){
				$('#mb-filter').val('dd-'+u_n+'-'+d_n).change()
			})
		}
		else{
			var arr=[[' .TotalBytes',dt]]
			updateRow(did,arr)
		}
	})
	if($('#devicesFooter').length==0){
		var nr=$('<tr/>').attr('id','devicesFooter').addClass('footer')
		nr.append($('<td/>').attr('colspan',4).text(':::Totals:::').addClass('a-r'))
		nr.append($('<td/>').addClass('num br2').attr('value',total))
		nr.append($('<td/>').text('-').addClass('a-c br percent'))
		$('#devicesData').append(nr)
	}
	else{
		var arr=[[' .TotalBytes',total]]
		updateRow('devicesFooter',arr)
	}

	setPercents('#devicesData tr', total)
	displayBytes('#devices-table');
}
function setPercents(rows, tot){
	var ctot=0
	$(rows).each(function(){
		var dt=Number($(this).find('.TotalBytes').attr('value'));
		var dp=dt/tot * 100
		ctot+=($(this).hasClass('is_d')?dp:0)
		dp=(dp > 0.1)? dp.toFixed(_dec):"-";
		var pcu=(dp > 100?'over-cap':(dp > 90?'cap-90':(dp > 80?'cap-80':(dp > 40?'cap-40':'cap-ok'))))
		$(this).find('.percent').text(dp).removeClass('over-cap cap-90 cap-80 cap-40 cap-ok').addClass(pcu)
	})
	$(rows).parents('table').find('.footer .percent').text(ctot.toFixed(_dec))
}
function displayBytes(range,override){
	var default_units=$("#DisplayUnits").val();
	var base=$("#DisplayBase").val();
	var cells= $(range).find('.num');
	$(cells).removeClass('isNull bytes Kbytes MBytes GBytes TBytes PBytes negative');
	$(cells).each(function(){
		var cell_val='N/A';
		var units='';
		var isneg='';
		var bytes=Number($(this).attr('value'));
		if (isNaN(bytes)){
			$(this).addClass('isNull')
			cell_val='-'
		}
		else{
			var unitsIndex=(default_units=== "auto")?(Math.floor((bytes==0?0:Math.log(Math.abs(bytes)))/Math.log(base))):default_units;
			unitsIndex=override||unitsIndex;
			cell_val=(bytes/Math.pow(base,Math.floor(unitsIndex))).toFixed(_dec);
			units=dispUnits[unitsIndex]+'ytes';
			isneg=cell_val<0?' negative':'';

		}
		$(this).html(cell_val).addClass(units+isneg);
	})
}
function showHideDevices(){
	var sz=$('#ShowZeroes').is(':checked')
	var sd=$('#ShowDevices').is(':checked')
	$('.TotalBytes').not('.isp').each(function(){
		var tp = $(this).parent('tr')
		if(tp.hasClass('summary-row')){
		   return
		}
		var bytes=$(this).attr('value');
		var is_z=(bytes==0)||(bytes=='-');
		var is_d=tp.hasClass('is_d') ;
		var is_v=$(this).is(':visible')
		var tid=tp.attr('id')
		if(!is_d||(is_d&&sd)){
			if (is_z&&sz&&!is_v) {
				tp.slideDown('slow')
		   }
			else if(is_z&&!sz&&is_v){
				tp.hide()
		   }
			else if(!is_z&&!is_v){
				tp.slideDown('slow')
		   }
		}
		else if(is_d&&!sd){
			if(is_v){
				tp.hide()
			}
		}
		else if(!is_v){
			tp.slideDown('slow')
		}
	})
	$('.ddl-device')[sd?'removeClass':'addClass']('hidden');
	$('.u-d').removeClass('c-u c-d').addClass(sd?'c-d':'c-u');
	$('.item-e')[sd?'removeClass':'addClass']('item-c');
	$('.isp')[$('#showISP').is(':checked')&&$('#mb-filter').val()=='dd-ALL'?'removeClass':'addClass']('hidden');
	$('.is-cap')[$('#bandwidth-u').is(':checked')?'hide':'show']()
	$('#correction-row')[$('.cf-desc').val()==''&&$('#correction-row .TotalBytes').attr('value')==0?'hide':'show']()
	$('#mcorrection-row')[$('#mcorrection-row .TotalBytes').attr('value')==0?'hide':'show']()
	if($('#correction-row').is(':visible')){
		$('#dailyFooter').show()
	}
	if($('#mcorrection-row').is(':visible')){
		$('#monthlyFooter').show()
	}
	if($('#daily-tab').hasClass('loaded'))DrawPie('Daily');
	if($('#monthly-tab').hasClass('loaded'))DrawPie('Monthly');
	if(_unlimited_usage=='1'&&$('#monthly-tab').hasClass('loaded')){
		DrawPie('Unlimited')
	}

}
function getDevice(p,v){
	var r,va=''
	 Object.keys(devices).forEach(function(d){
		switch(p){
			case 'device':
				if(devices[d].device==v){
					r=d
				}
				break
			case 'id':
				if(devices[d].id==v){
					r=d
				}
				break
		   case 'ip':
				if(devices[d].ip==v){
					r=d
				}
				break
			default:
				break
		}
	})
	return r
}
function getUsage(p,v){
	var r=[]
	usage.forEach(function(k){
		if(k[p]==v) r.push(k)
	})
	return r.sort(function(a, b) { return (a.name > b.name?1:(a.name < b.name?-1:0)); })
}
function flushChanges(){
	$('.num').attr('title','').removeClass('changed c0 c1 c2 c3 c4 c5');
}
function newdate(d,o){
	return new Date(d.getFullYear(),d.getMonth(),d.getDate()+o);
}
function delLS(i) {
	if(confirm('Are you sure you want to delete this history entry?\nThis will also reload the data.')){
		$('#'+i).remove()
		localStorage.removeItem(i)
		var fn=$('.currentSummary').attr('id')
		load_data(fn)
	}
}
function addcorrection(){
	$('#correction-row,#remove-correction').slideDown('slow')
	$('#no-daily-data,#add-correction').slideUp('slow')
}
function removecorrection(){
	if(confirm('Are you sure you want to delete the correction for this date?')){
		$('#correction-row input').val('').change()
		$('#correction-row,#remove-correction').slideUp('slow')
		$('#add-correction').slideDown('slow')
		$('#no-daily-data')[$('#DailyData tr').length==0?'slideDown':'slideUp']('slow')
		$('#dailyFooter')[$('#DailyData tr').length==0?'slideUp':'slideDown']('slow')
		$('#MonthlyBreakdown, #breakdownFooter').html('')
	}
}
function settings(wo){
	if(wo=='reset'){
		if(!confirm('Are you sure that you want to clear all localStorage variables stored for YAMon?')){
			return
		}
		localStorage.Clear()
	}
	else if(wo=='export'){
		$('#SECTION_TWO').append("<div id='settings'><h3>Export Settings</h3><p>All of the settings, etc. for this web app are retained in localStorage (meaning that they are private to this browser on this computer).  This is my quick & dirty method (emphasis on the latter) for copying your settings to different browser or device.</p><p>Copy the text from the field below to a file on a USB stick or email it to yourself and then open the `Settings` tab on the other machine (or browser) and click `Import`.</p><textarea rows=16 cols=80></textarea><p><button onclick=close_settings()>Close</button></p>")
		var ts=JSON.stringify(localStorage)
		$('#settings textarea').val(ts)
	}
	else{
		$('#SECTION_TWO').append("<div id='settings'><h3>Import Settings</h3><p>Paste the settings you exported previously into the field below and then click `Import`.</p><p><b>NOTE</b> - this replace all similarly named variables within the localStorage for this browser on this machine.  <i>It cannot be undone!</i>  I strongly recommend that you first export the settings from this machine... just in case!</p><textarea rows=16 cols=80></textarea><p><button onclick=import_settings()>Import</button><button onclick=close_settings()>Cancel</button></p>")
	}
}
function close_settings(){
	$('#settings').slideUp('slow').remove()
}
function import_settings(){
	if(!confirm("Are you sure you want to do this?  Have you already backed up the settings from this machine (by exporting them)?\n\nRemember that you cannot undo this operation without a backup... you've been warned!  Click `Cancel` to chicken out.")){
		close_settings()
		return false
	}
	var nv=JSON.parse($('#settings textarea').val())
	Object.keys(nv).forEach(function(k){
		localStorage.setItem(k,nv[k])
	})
	location.reload();
}
function changeUnits(wo){
	var ct=$(wo).text().toLowerCase()
	var ns=ct=='auto'?ct:2
	$('#DisplayUnits').val(ns).change()
	$('.change-units a').hide();
	$('.change-units a')[$('#DisplayUnits').val()=='auto'?'first':'last']().show()

}